diff --git a/Content.Client/Silicons/Borgs/BorgSystem.cs b/Content.Client/Silicons/Borgs/BorgSystem.cs index 517027d0821..0e3de6f3ece 100644 --- a/Content.Client/Silicons/Borgs/BorgSystem.cs +++ b/Content.Client/Silicons/Borgs/BorgSystem.cs @@ -74,6 +74,10 @@ public sealed partial class BorgSystem : SharedBorgSystem if (!Resolve(ent, ref ent.Comp1, ref ent.Comp2, ref ent.Comp3)) return; + // DeltaV - Start Skip Light layer for Replicators. + if (!_sprite.LayerMapTryGet((ent.Owner, ent.Comp3), BorgVisualLayers.Light, out _, false)) + return; + // DeltaV - End Skip Light layer for Replicators. if (_appearance.TryGetData(ent.Owner, MobStateVisuals.State, out var state, ent.Comp2)) { if (state != MobState.Alive) @@ -134,4 +138,4 @@ public sealed partial class BorgSystem : SharedBorgSystem base.Update(frameTime); UpdateBattery(frameTime); } -} +} \ No newline at end of file diff --git a/Content.Client/_Impstation/Replicator/ReplicatorNestFallingVisualsSystem.cs b/Content.Client/_Impstation/Replicator/ReplicatorNestFallingVisualsSystem.cs new file mode 100644 index 00000000000..0828464448d --- /dev/null +++ b/Content.Client/_Impstation/Replicator/ReplicatorNestFallingVisualsSystem.cs @@ -0,0 +1,70 @@ +using Content.Shared._Impstation.Replicator; +using Robust.Client.Animations; +using Robust.Client.GameObjects; +using Robust.Shared.Animations; + +namespace Content.Client._Impstation.Replicator; + +public sealed class ReplicatorNestFallingVisualsSystem : EntitySystem +{ + [Dependency] private readonly AnimationPlayerSystem _anim = default!; + + private const string HoleFallingAnimationKey = "hole_fall"; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnComponentInit); + SubscribeLocalEvent(OnComponentRemove); + } + + private void OnComponentInit(Entity ent, ref ComponentInit args) + { + if (!TryComp(ent, out var sprite) || TerminatingOrDeleted(ent)) + return; + + ent.Comp.OriginalScale = sprite.Scale; + var animPlayer = EnsureComp(ent); + if (_anim.HasRunningAnimation(animPlayer, HoleFallingAnimationKey)) + return; + + _anim.Play((ent, animPlayer), GetFallingAnimation(ent.Comp), HoleFallingAnimationKey); + } + + private void OnComponentRemove(Entity ent, ref ComponentRemove args) + { + if (!TryComp(ent, out var sprite) || TerminatingOrDeleted(ent)) + return; + + var animPlayer = EnsureComp(ent); + var animEnt = (Entity) (ent, animPlayer); + if (_anim.HasRunningAnimation(animPlayer, HoleFallingAnimationKey)) + _anim.Stop(animEnt, HoleFallingAnimationKey); + + sprite.Scale = ent.Comp.OriginalScale; + } + + private static Animation GetFallingAnimation(ReplicatorNestFallingComponent component) + { + var length = component.AnimationTime; + return new Animation + { + Length = length, + AnimationTracks = + { + new AnimationTrackComponentProperty + { + ComponentType = typeof(SpriteComponent), + Property = nameof(SpriteComponent.Scale), + KeyFrames = + { + new AnimationTrackProperty.KeyFrame(component.OriginalScale, 0.0f), + new AnimationTrackProperty.KeyFrame(component.AnimationScale, length.Seconds), + }, + InterpolationMode = AnimationInterpolationMode.Cubic, + }, + }, + }; + } +} diff --git a/Content.Client/_Impstation/Replicator/ReplicatorNestVisualsSystem.cs b/Content.Client/_Impstation/Replicator/ReplicatorNestVisualsSystem.cs new file mode 100644 index 00000000000..ffe1a4c780c --- /dev/null +++ b/Content.Client/_Impstation/Replicator/ReplicatorNestVisualsSystem.cs @@ -0,0 +1,44 @@ +using Content.Shared._Impstation.Replicator; +using Robust.Client.GameObjects; + +namespace Content.Client._Impstation.Replicator; + +public sealed partial class ReplicatorNestVisualsSystem : SharedReplicatorNestSystem +{ + [Dependency] private readonly AppearanceSystem _appearance = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnEmbiggened); + } + + private void OnEmbiggened(Entity ent, ref ReplicatorNestEmbiggenedEvent args) + { + if (!TryComp(ent, out var sprite)) + return; + + var targetLayer = ent.Comp.CurrentLevel switch + { + >= 3 => ReplicatorNestVisuals.Level3, + 2 => ReplicatorNestVisuals.Level2, + _ => ReplicatorNestVisuals.Level1, + }; + + var targetLayerUnshaded = ent.Comp.CurrentLevel switch + { + >= 3 => ReplicatorNestVisuals.Level3Unshaded, + 2 => ReplicatorNestVisuals.Level2Unshaded, + _ => ReplicatorNestVisuals.Level1Unshaded, + }; + + if (!sprite.LayerMapTryGet(targetLayer, out var layerIndex) || + !sprite.LayerMapTryGet(targetLayerUnshaded, out var layerIndexUnshaded)) + return; + + sprite.LayerSetVisible(layerIndex, true); + sprite.LayerSetVisible(layerIndexUnshaded, true); + _appearance.OnChangeData(ent.Owner, sprite); + } +} diff --git a/Content.Client/_Impstation/Replicator/ReplicatorVisualsSystem.cs b/Content.Client/_Impstation/Replicator/ReplicatorVisualsSystem.cs new file mode 100644 index 00000000000..aac1db3111f --- /dev/null +++ b/Content.Client/_Impstation/Replicator/ReplicatorVisualsSystem.cs @@ -0,0 +1,54 @@ +using Content.Client.DamageState; +using Content.Shared.CombatMode; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Systems; +using Content.Shared._Impstation.Replicator; +using Robust.Client.GameObjects; + +namespace Content.Client._Impstation.Replicator; + +public sealed class ReplicatorVisualsSystem : EntitySystem +{ + [Dependency] private readonly AppearanceSystem _appearance = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnAppearanceChange); + SubscribeLocalEvent(OnToggleCombat); + SubscribeLocalEvent(OnMobStateChanged); + } + + private void OnToggleCombat(Entity ent, ref ToggleCombatActionEvent args) + { + if (TryComp(ent, out var sprite)) + _appearance.OnChangeData(ent, sprite); + } + + private void OnAppearanceChange(Entity ent, ref AppearanceChangeEvent args) + { + if (args.Sprite == null || !TryComp(ent, out var combat)) + return; + + if (!args.Sprite.LayerMapTryGet(ReplicatorVisuals.Combat, out var layerIndex) || + !args.Sprite.LayerMapTryGet(DamageStateVisualLayers.Base, out var baseIndex)) + return; + + if (!args.Sprite.TryGetLayer(layerIndex, out var combatLayer) || + !args.Sprite.TryGetLayer(baseIndex, out var baseLayer)) + return; + + args.Sprite.LayerSetVisible(layerIndex, _mobState.IsAlive(ent) && combat.IsInCombatMode); + combatLayer.SetAnimationTime(baseLayer.AnimationTime); + combatLayer.AnimationFrame = baseLayer.AnimationFrame; + combatLayer.AnimationTimeLeft = baseLayer.AnimationTimeLeft; + } + + private void OnMobStateChanged(Entity ent, ref MobStateChangedEvent args) + { + if (TryComp(ent, out var sprite)) + _appearance.OnChangeData(ent, sprite); + } +} diff --git a/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs b/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs index 7090ca77ef5..8e687860f33 100644 --- a/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs +++ b/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs @@ -47,6 +47,7 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem _physicsQuery = GetEntityQuery(); SubscribeLocalEvent(PreventConsume); + SubscribeLocalEvent(PreventConsume); // DeltaV - Singulo stability for mass delete Replicators. SubscribeLocalEvent(PreventConsume); SubscribeLocalEvent(OnHorizonMapInit); SubscribeLocalEvent(OnStartCollide); diff --git a/Content.Server/_Impstation/Replicator/ReplicatorNestSystem.cs b/Content.Server/_Impstation/Replicator/ReplicatorNestSystem.cs new file mode 100644 index 00000000000..0bd605deccb --- /dev/null +++ b/Content.Server/_Impstation/Replicator/ReplicatorNestSystem.cs @@ -0,0 +1,391 @@ +using System.Linq; +using Content.Server.Actions; +using Content.Server.Audio; +using Content.Server.Buckle.Systems; +using Content.Server.GameTicking; +using Content.Server.Pinpointer; +using Content.Server.Popups; +using Content.Server.Storage.EntitySystems; +using Content.Server.Stunnable; +using Content.Shared.Actions; +using Content.Shared.Buckle.Components; +using Content.Shared.Destructible; +using Content.Shared.Inventory; +using Content.Shared.Item; +using Content.Shared.Mind.Components; +using Content.Shared.Mobs.Components; +using Content.Shared.Mobs.Systems; +using Content.Shared.Movement.Pulling; +using Content.Shared.Movement.Events; +using Content.Shared.Movement.Pulling.Components; +using Content.Shared.Movement.Pulling.Events; +using Content.Shared.Movement.Pulling.Systems; +using Content.Shared.Movement.Systems; +using Content.Shared.Pinpointer; +using Content.Shared.Popups; +using Content.Shared.StepTrigger.Systems; +using Content.Shared.Storage.Components; +using Content.Shared.Stunnable; +using Content.Shared.Throwing; +using Content.Shared.Whitelist; +using Content.Shared._Impstation.Replicator; +using Robust.Server.Containers; +using Robust.Server.GameObjects; +using Robust.Shared.Containers; +using Robust.Shared.Player; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Server._Impstation.Replicator; + +public sealed class ReplicatorNestSystem : SharedReplicatorNestSystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SharedReplicatorNestSystem _sharedNest = default!; + [Dependency] private readonly ActionsSystem _actions = default!; + [Dependency] private readonly ActionContainerSystem _actionContainer = default!; + [Dependency] private readonly ContainerSystem _containerSystem = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly NavMapSystem _navMap = default!; + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly StunSystem _stun = default!; + [Dependency] private readonly MovementModStatusSystem _movementMod = default!; + [Dependency] private readonly TransformSystem _xform = default!; + [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly PinpointerSystem _pinpointer = default!; + [Dependency] private readonly AmbientSoundSystem _ambientSound = default!; + [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; + [Dependency] private readonly PullingSystem _pulling = default!; + [Dependency] private readonly ThrowingSystem _throwing = default!; + [Dependency] private readonly EntityStorageSystem _entStorage = default!; + [Dependency] private readonly BuckleSystem _buckle = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnEntRemoved); + SubscribeLocalEvent(OnStepTriggerAttempt); + SubscribeLocalEvent(OnStepTriggered); + SubscribeLocalEvent(OnUpdateCanMove); + SubscribeLocalEvent(OnFallingPickupAttempt); + SubscribeLocalEvent(OnFallingGettingPickedUpAttempt); + SubscribeLocalEvent(OnFallingPullAttempt); + SubscribeLocalEvent(OnDestroyed); + SubscribeLocalEvent(OnShutdown); + SubscribeLocalEvent(OnRoundEndTextAppend); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + HashSet toDel = []; + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var falling)) + { + if (_timing.CurTime < falling.NextDeletionTime) + continue; + + if (!TryComp(falling.FallingTarget, out var nestComp)) + continue; + + if (_whitelist.IsWhitelistPass(nestComp.PreservationBlacklist, uid)) + { + toDel.Add(uid); + } + else if (!_whitelist.IsWhitelistPass(nestComp.PreservationWhitelist, uid)) + { + if (!TryComp(uid, out var mindComp) || !mindComp.HasMind) + toDel.Add(uid); + } + + _containerSystem.Insert(uid, nestComp.Hole); + EnsureComp(uid); + RemCompDeferred(uid, falling); + } + + foreach (var uid in toDel) + { + QueueDel(uid); + } + } + + private void OnEntRemoved(Entity ent, ref EntRemovedFromContainerMessage args) + { + RemCompDeferred(args.Entity); + } + + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + if (!Transform(ent).Coordinates.IsValid(EntityManager)) + { + QueueDel(ent); + return; + } + + ent.Comp.Hole = _containerSystem.EnsureContainer(ent, "hole"); + ent.Comp.NextSpawnAt = ent.Comp.SpawnNewAt; + ent.Comp.NextUpgradeAt = ent.Comp.UpgradeAt; + ent.Comp.NextTileConvertAt = ent.Comp.TileConvertAt; + + CleanupPointsStorage(ent); + var pointsStorageEnt = Spawn("ReplicatorNestPointsStorage", Transform(ent).Coordinates); + _xform.SetParent(pointsStorageEnt, ent); + EnsureComp(pointsStorageEnt); + ent.Comp.PointsStorage = pointsStorageEnt; + } + + private void OnShutdown(Entity ent, ref ComponentShutdown args) + { + CleanupPointsStorage(ent); + } + + private void OnStepTriggerAttempt(Entity ent, ref StepTriggerAttemptEvent args) + { + args.Continue = true; + } + + private void OnStepTriggered(Entity ent, ref StepTriggeredOffEvent args) + { + if (HasComp(args.Tripper)) + return; + + if (_whitelist.IsWhitelistPass(ent.Comp.Blacklist, args.Tripper)) + { + if (TryComp(args.Tripper, out var pullable) && pullable.BeingPulled) + _pulling.TryStopPull(args.Tripper, pullable); + + var xform = Transform(ent); + var xformQuery = GetEntityQuery(); + var worldPos = _xform.GetWorldPosition(xform, xformQuery); + var direction = _xform.GetWorldPosition(args.Tripper, xformQuery) - worldPos; + _throwing.TryThrow(args.Tripper, direction * 10, 7, ent, 0); + return; + } + + var isReplicator = HasComp(args.Tripper); + if (TryComp(args.Tripper, out var mobState) && isReplicator && _mobState.IsDead(args.Tripper)) + { + _sharedNest.StartFalling(ent, args.Tripper); + return; + } + + if (mobState != null && _mobState.IsAlive(args.Tripper)) + return; + + if (TryComp(args.Tripper, out var entStorage)) + _entStorage.EmptyContents(args.Tripper, entStorage); + + if (TryComp(args.Tripper, out var strapComp) && strapComp.BuckledEntities.Count > 0) + { + foreach (var buckled in strapComp.BuckledEntities) + { + if (!TryComp(buckled, out var buckleComp)) + continue; + + _buckle.Unbuckle((args.Tripper, buckleComp), null); + } + } + + _sharedNest.StartFalling(ent, args.Tripper); + } + + private void OnUpdateCanMove(Entity ent, ref UpdateCanMoveEvent args) + { + args.Cancel(); + } + + private void OnFallingPickupAttempt(Entity ent, ref PickupAttemptEvent args) + { + args.Cancel(); + } + + private void OnFallingGettingPickedUpAttempt(Entity ent, ref GettingPickedUpAttemptEvent args) + { + args.Cancel(); + } + + private void OnFallingPullAttempt(Entity ent, ref PullAttemptEvent args) + { + args.Cancelled = true; + } + + private void OnDestroyed(Entity ent, ref DestructionEventArgs args) + { + HandleDestruction(ent); + } + + private void HandleDestruction(Entity ent) + { + if (TryComp(ent.Comp.PointsStorage, out var lightComp)) + RemComp(ent.Comp.PointsStorage); + + foreach (var uid in _containerSystem.EmptyContainer(ent.Comp.Hole)) + { + RemCompDeferred(uid); + _stun.TryKnockdown(uid, TimeSpan.FromSeconds(2), false); + } + + foreach (var spawner in ent.Comp.UnclaimedSpawners.ToArray()) + { + ent.Comp.UnclaimedSpawners.Remove(spawner); + QueueDel(spawner); + } + + var fallingQuery = EntityQueryEnumerator(); + while (fallingQuery.MoveNext(out var uid, out var comp)) + { + if (ent.Owner == comp.FallingTarget) + RemCompDeferred(uid); + } + + EntityUid? queen = null; + var livingReplicators = new HashSet(); + var repQuery = EntityQueryEnumerator(); + while (repQuery.MoveNext(out var uid, out var comp)) + { + if (!_mobState.IsAlive(uid) || comp.MyNest != ent.Owner) + continue; + + comp.MyNest = null; + if (comp.Queen) + queen = uid; + + livingReplicators.Add(uid); + } + + if (livingReplicators.Count > 0) + { + var queenNotNull = queen ?? _random.Pick(livingReplicators); + var queenComp = EnsureComp(queenNotNull); + queenComp.Queen = true; + + var related = new HashSet>(); + foreach (var rep in livingReplicators) + { + if (TryComp(rep, out var repComp)) + related.Add((rep, repComp)); + } + + queenComp.RelatedReplicators = related; + + var upgradedQueen = ForceUpgrade((queenNotNull, queenComp), queenComp.FinalStage); + if (upgradedQueen is { } upgradedQueenNotNull && TryComp(upgradedQueenNotNull, out var upgradedComp)) + { + queen = upgradedQueenNotNull; + livingReplicators.Remove(queenNotNull); + livingReplicators.Add(upgradedQueenNotNull); + + if (TryComp(upgradedQueenNotNull, out var mindContainer) && mindContainer.Mind is { } mind) + { + if (!mindContainer.HasMind) + upgradedComp.Actions.Add(_actions.AddAction(upgradedQueenNotNull, upgradedComp.SpawnNewNestAction)); + else + upgradedComp.Actions.Add(_actionContainer.AddAction(mind, upgradedComp.SpawnNewNestAction)); + } + } + else + { + queen = queenNotNull; + if (TryComp(queenNotNull, out var mindContainer) && mindContainer.Mind is { } mind) + { + if (!mindContainer.HasMind) + queenComp.Actions.Add(_actions.AddAction(queenNotNull, queenComp.SpawnNewNestAction)); + else + queenComp.Actions.Add(_actionContainer.AddAction(mind, queenComp.SpawnNewNestAction)); + } + } + } + + foreach (var uid in livingReplicators) + { + if (!TryComp(uid, out var comp)) + continue; + + var upgradedNotNull = uid == queen ? uid : ForceUpgrade((uid, comp), comp.FirstStage) ?? uid; + + _movementMod.TryUpdateMovementSpeedModDuration(upgradedNotNull, "HoleDestroyedSlowdownStatusEffect", TimeSpan.FromSeconds(3), 0.8f); + + if (_inventory.TryGetSlotEntity(upgradedNotNull, "pocket1", out var pocket1) && + TryComp(pocket1, out var pinpointer)) + { + _pinpointer.SetTarget(pocket1.Value, queen, pinpointer); + } + + var pinpointerQuery = EntityQueryEnumerator(); + while (pinpointerQuery.MoveNext(out var pinUid, out var pinComp, out var pinXform)) + { + if (pinXform.ParentUid == upgradedNotNull) + _pinpointer.SetTarget(pinUid, queen, pinComp); + } + + _popup.PopupEntity(Loc.GetString("replicator-nest-destroyed"), uid, uid, PopupType.LargeCaution); + } + } + + private void CleanupPointsStorage(Entity ent) + { + var pointsStorage = ent.Comp.PointsStorage; + if (pointsStorage == default) + return; + + if (Exists(pointsStorage) && pointsStorage != ent.Owner) + QueueDel(pointsStorage); + + ent.Comp.PointsStorage = default; + } + + private void OnRoundEndTextAppend(RoundEndTextAppendEvent args) + { + List> nests = []; + var query = AllEntityQuery(); + while (query.MoveNext(out var uid, out var comp)) + { + nests.Add((uid, comp)); + } + + if (nests.Count == 0) + return; + + args.AddLine(string.Empty); + + var totalPoints = 0; + var totalSpawned = 0; + HashSet levels = []; + var locationsList = string.Empty; + var i = 0; + foreach (var ent in nests) + { + i++; + var pointsStorage = ent.Comp; + var location = "Unknown"; + var mapCoords = _xform.ToMapCoordinates(Transform(ent).Coordinates); + if (_navMap.TryGetNearestBeacon(mapCoords, out var beacon, out _) && beacon != null && beacon.Value.Comp.Text != null) + location = beacon.Value.Comp.Text!; + + if (nests.Count == 1) + locationsList = string.Concat(locationsList, "[color=#d70aa0]", location, "[/color]."); + else if (nests.Count == 2 && i == 1) + locationsList = string.Concat(locationsList, "[color=#d70aa0]", location, " "); + else if (i != nests.Count) + locationsList = string.Concat(locationsList, "[color=#d70aa0]", location, "[/color], "); + else + locationsList = string.Concat(locationsList, "and [color=#d70aa0]", location, "[/color]."); + + totalPoints += pointsStorage.TotalPoints / 10; + totalSpawned += pointsStorage.TotalReplicators; + levels.Add(pointsStorage.Level); + } + + args.AddLine(Loc.GetString( + "replicator-nest-end-of-round", + ("location", locationsList), + ("level", levels.Max()), + ("points", totalPoints), + ("replicators", totalSpawned))); + args.AddLine(string.Empty); + } +} diff --git a/Content.Server/_Impstation/Replicator/ReplicatorSystem.cs b/Content.Server/_Impstation/Replicator/ReplicatorSystem.cs new file mode 100644 index 00000000000..01489d86979 --- /dev/null +++ b/Content.Server/_Impstation/Replicator/ReplicatorSystem.cs @@ -0,0 +1,216 @@ +using Content.Server.Actions; +using Content.Server.Ghost.Roles.Events; +using Content.Server.Pinpointer; +using Content.Server.Popups; +using Content.Server.Stunnable; +using Content.Shared.Actions; +using Content.Shared.Body.Part; +using Content.Shared.CombatMode; +using Content.Shared.Emp; +using Content.Shared.Hands.Components; +using Content.Shared.Hands.EntitySystems; +using Content.Shared.Interaction.Events; +using Content.Shared.Inventory; +using Content.Shared.Mind.Components; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Systems; +using Content.Shared.Pinpointer; +using Content.Shared.Popups; +using Content.Shared._Impstation.Replicator; +using Content.Shared._Impstation.SpawnedFromTracker; +using Robust.Server.GameObjects; +using Robust.Shared.Map; +using Robust.Shared.Timing; +using System.Linq; + +namespace Content.Server._Impstation.Replicator; + +public sealed class ReplicatorSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly ActionsSystem _actions = default!; + [Dependency] private readonly AppearanceSystem _appearance = default!; + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly StunSystem _stun = default!; + [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly PinpointerSystem _pinpointer = default!; + [Dependency] private readonly SharedHandsSystem _hands = default!; + [Dependency] private readonly SharedReplicatorNestSystem _replicatorNest = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMindAdded); + SubscribeLocalEvent(OnMindRemoved); + SubscribeLocalEvent(OnAttackAttempt); + SubscribeLocalEvent(OnCombatToggle); + SubscribeLocalEvent(OnGhostRoleSpawnerUsed); + SubscribeLocalEvent(OnSpawnNestAction); + SubscribeLocalEvent(OnEmpPulse); + SubscribeLocalEvent(OnMobStateChanged); + SubscribeLocalEvent(OnReplicatorMapInit); + SubscribeLocalEvent(OnBodyPartAdded); + } + + private void OnReplicatorMapInit(Entity ent, ref MapInitEvent args) + { + CleanupInheritedHands(ent); + } + + private void OnBodyPartAdded(Entity ent, ref BodyPartAddedEvent args) + { + CleanupInheritedHands(ent); + } + + private void OnMindAdded(Entity ent, ref MindAddedMessage args) + { + CleanupInheritedHands(ent); + + if (ent.Comp.HasSpawnedNest) + return; + + if (!ent.Comp.Queen) + return; + + ent.Comp.Actions.Add(_actions.AddAction(ent, ent.Comp.SpawnNewNestAction)); + + ent.Comp.HasSpawnedNest = true; + } + + private void OnMindRemoved(Entity ent, ref MindRemovedMessage args) + { + foreach (var action in ent.Comp.Actions) + { + QueueDel(action); + } + } + + private void OnSpawnNestAction(Entity ent, ref ReplicatorSpawnNestActionEvent args) + { + if (!_timing.IsFirstTimePredicted) + return; + + var xform = Transform(ent); + var coords = xform.Coordinates; + if (!coords.IsValid(EntityManager) || xform.MapID == MapId.Nullspace) + return; + + var myNest = Spawn("ReplicatorNest", xform.Coordinates); + var myNestComp = EnsureComp(myNest); + + if (ent.Comp.RelatedReplicators.Count <= 0 || ent.Comp.Queen && !ent.Comp.RelatedReplicators.Contains(ent)) + ent.Comp.RelatedReplicators.Add(ent); + + HashSet newMinions = []; + HashSet<(EntityUid, ReplicatorComponent)> livingReplicators = []; + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var comp)) + { + livingReplicators.Add((uid, comp)); + } + + foreach (var (uid, comp) in livingReplicators) + { + newMinions.Add(uid); + + if (_inventory.TryGetSlotEntity(uid, "pocket1", out var pocket1) && TryComp(pocket1, out var pinpointer)) + _pinpointer.SetTarget(pocket1.Value, myNest, pinpointer); + + var pinpointerQuery = EntityQueryEnumerator(); + while (pinpointerQuery.MoveNext(out var pinUid, out var pinComp, out var pinXform)) + { + if (pinXform.ParentUid == uid) + _pinpointer.SetTarget(pinUid, myNest, pinComp); + } + + comp.MyNest = myNest; + } + + myNestComp.SpawnedMinions = newMinions; + myNestComp.SpawnedMinions.Add(ent); + ent.Comp.MyNest = myNest; + ent.Comp.RelatedReplicators.Clear(); + ent.Comp.Queen = false; + + _replicatorNest.ForceUpgrade(ent, ent.Comp.FirstStage); + } + + private void OnGhostRoleSpawnerUsed(Entity ent, ref GhostRoleSpawnerUsedEvent args) + { + CleanupInheritedHands(ent); + + if (!TryComp(args.Spawner, out var tracker) || + !TryComp(tracker.SpawnedFrom, out var nestComp)) + return; + + nestComp.SpawnedMinions.Add(ent); + nestComp.UnclaimedSpawners.Remove(args.Spawner); + ent.Comp.MyNest = tracker.SpawnedFrom; + } + + private void OnAttackAttempt(Entity ent, ref AttackAttemptEvent args) + { + if (HasComp(args.Target)) + { + _popup.PopupEntity(Loc.GetString("replicator-on-replicator-attack-fail"), ent, ent, PopupType.MediumCaution); + args.Cancel(); + } + + if (HasComp(args.Target)) + { + _popup.PopupEntity(Loc.GetString("replicator-on-nest-attack-fail"), ent, ent, PopupType.MediumCaution); + args.Cancel(); + } + } + + private void OnCombatToggle(Entity ent, ref ToggleCombatActionEvent args) + { + if (!TryComp(ent, out var combat)) + return; + + _appearance.SetData(ent, ReplicatorVisuals.Combat, combat.IsInCombatMode); + } + + private void OnMobStateChanged(Entity ent, ref MobStateChangedEvent args) + { + if (_mobState.IsAlive(ent)) + return; + + _appearance.SetData(ent, ReplicatorVisuals.Combat, false); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var replicatorComp)) + { + _popup.PopupEntity(Loc.GetString(replicatorComp.QueenDiedMessage), uid, uid, PopupType.LargeCaution); + } + } + + private void OnEmpPulse(Entity ent, ref EmpPulseEvent args) + { + args.Affected = true; + args.Disabled = true; + _stun.TryUpdateParalyzeDuration(ent, ent.Comp.EmpStunTime); + } + + private void CleanupInheritedHands(Entity ent) + { + if (!TryComp(ent, out var handsComp)) + return; + + foreach (var handId in handsComp.Hands.Keys.ToArray()) + { + if (ent.Comp.Queen) + { + _hands.RemoveHand((ent.Owner, handsComp), handId); + continue; + } + + if (handId.Contains("-hand-")) + continue; + + _hands.RemoveHand((ent.Owner, handsComp), handId); + } + } +} diff --git a/Content.Server/_Impstation/Replicator/Roles/ReplicatorRoleComponent.cs b/Content.Server/_Impstation/Replicator/Roles/ReplicatorRoleComponent.cs new file mode 100644 index 00000000000..6e8b1dc7023 --- /dev/null +++ b/Content.Server/_Impstation/Replicator/Roles/ReplicatorRoleComponent.cs @@ -0,0 +1,6 @@ +using Content.Shared.Roles.Components; + +namespace Content.Server._Impstation.Replicator.Roles; + +[RegisterComponent] +public sealed partial class ReplicatorRoleComponent : BaseMindRoleComponent; diff --git a/Content.Shared/Silicons/Borgs/SharedBorgSystem.Module.cs b/Content.Shared/Silicons/Borgs/SharedBorgSystem.Module.cs index 3095190710a..68d529fc09f 100644 --- a/Content.Shared/Silicons/Borgs/SharedBorgSystem.Module.cs +++ b/Content.Shared/Silicons/Borgs/SharedBorgSystem.Module.cs @@ -239,7 +239,7 @@ public abstract partial class SharedBorgSystem _hands.RemoveHand((chassis.Owner, hands), handId); } - + module.Comp.Spawned = false; // DeltaV - replicators reset spawned modules on unselect. Dirty(module); } #endregion diff --git a/Content.Shared/_Impstation/Replicator/ReplicatorComponent.cs b/Content.Shared/_Impstation/Replicator/ReplicatorComponent.cs new file mode 100644 index 00000000000..a315088b7d0 --- /dev/null +++ b/Content.Shared/_Impstation/Replicator/ReplicatorComponent.cs @@ -0,0 +1,51 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; + +namespace Content.Shared._Impstation.Replicator; + +[RegisterComponent, NetworkedComponent] +public sealed partial class ReplicatorComponent : Component +{ + [DataField] + public TimeSpan EmpStunTime = TimeSpan.FromSeconds(5); + + [DataField] + public bool Queen; + + [DataField] + public int UpgradeStage; + + public HashSet> RelatedReplicators = []; + + public EntityUid? MyNest; + + [DataField] + public HashSet UpgradeActions = []; + + [DataField] + public string ReadyToUpgradeMessage = "replicator-upgrade-t1"; + + [DataField] + public EntProtoId SpawnNewNestAction = "ActionReplicatorSpawnNest"; + + public HashSet Actions = []; + + public bool HasSpawnedNest; + public bool HasBeenGivenUpgradeActions; + + [DataField] + public LocId QueenDiedMessage = "replicator-queen-died-msg"; + + [DataField] + public EntProtoId FirstStage = "MobReplicator"; + + [DataField] + public EntProtoId FinalStage = "MobReplicatorTier3"; +} + +[Serializable, NetSerializable] +public enum ReplicatorVisuals : byte +{ + Combat +} diff --git a/Content.Shared/_Impstation/Replicator/ReplicatorNestComponent.cs b/Content.Shared/_Impstation/Replicator/ReplicatorNestComponent.cs new file mode 100644 index 00000000000..05bb513aa98 --- /dev/null +++ b/Content.Shared/_Impstation/Replicator/ReplicatorNestComponent.cs @@ -0,0 +1,121 @@ +using Content.Shared.Maps; +using Content.Shared.Whitelist; +using Robust.Shared.Audio; +using Robust.Shared.Containers; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; + +namespace Content.Shared._Impstation.Replicator; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class ReplicatorNestComponent : Component +{ + public readonly int MaxUpgradeStage = 2; + + public Container Hole = default!; + + [DataField] + public EntityWhitelist Blacklist = new(); + + [DataField] + public EntityWhitelist PreservationWhitelist = new(); + + [DataField] + public EntityWhitelist PreservationBlacklist = new(); + + [DataField(readOnly: true)] + public int TotalPoints; + + [DataField(readOnly: true)] + public int SpawningProgress; + + [DataField(readOnly: true), AutoNetworkedField] + public int CurrentLevel = 1; + + [DataField] + public int BonusPointsAlive = 10; + + [DataField] + public int BonusPointsHumanoid; + + [DataField] + public int TileConvertAt = 100; + + [DataField] + public int SpawnNewAt = 300; + + [DataField] + public int UpgradeAt = 400; + + [DataField] + public int EndgameLevel = 3; + + [DataField] + public int AnnounceAtLevel = 5; + + [DataField] + public LocId Announcement = "replicator-level-warning"; + + public bool HasAnnounced; + + [DataField] + public float TileConversionChance = 0.05f; + + [DataField] + public float TileConversionRadius = 1f; + + [DataField] + public float TileConversionIncrease = 1f; + + [DataField] + public EntProtoId ToSpawn = "SpawnPointGhostReplicator"; + + [DataField] + public EntProtoId SpawnNewNestAction = "ActionReplicatorSpawnNest"; + + [DataField] + public SoundSpecifier FallingSound = new SoundPathSpecifier("/Audio/_Impstation/Effects/falling.ogg"); + + [DataField] + public SoundSpecifier LevelUpSound = new SoundPathSpecifier("/Audio/_Impstation/Ambience/hole_2.ogg"); + + [DataField] + public SoundSpecifier UpgradeSound = new SoundPathSpecifier("/Audio/_Impstation/Misc/replicator_sfx2.ogg"); + + [DataField] + public SoundSpecifier TilePlaceSound = new SoundPathSpecifier("/Audio/_Impstation/Misc/replicator_sfx1.ogg"); + + [DataField] + public ProtoId ConversionTile = "FloorReplicator"; + + [DataField] + public EntProtoId TileConversionVfx = "ReplicatorFloorSpawnVFX"; + + public HashSet SpawnedMinions = []; + public HashSet UnclaimedSpawners = []; + public int NextSpawnAt; + public int NextUpgradeAt; + public int NextTileConvertAt; + + [DataField, AutoNetworkedField] + public bool NeedsUpdate; + + public EntityUid PointsStorage; +} + +[Serializable, NetSerializable] +public enum ReplicatorNestVisuals : byte +{ + Level1, + Level2, + Level3, + Level1Unshaded, + Level2Unshaded, + Level3Unshaded, +} + +[Serializable, NetSerializable] +public sealed partial class ReplicatorNestSizeChangedEvent : EntityEventArgs +{ +} diff --git a/Content.Shared/_Impstation/Replicator/ReplicatorNestFallingComponent.cs b/Content.Shared/_Impstation/Replicator/ReplicatorNestFallingComponent.cs new file mode 100644 index 00000000000..764d748ee3e --- /dev/null +++ b/Content.Shared/_Impstation/Replicator/ReplicatorNestFallingComponent.cs @@ -0,0 +1,28 @@ +using System.Numerics; +using Robust.Shared.GameStates; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Shared._Impstation.Replicator; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, AutoGenerateComponentPause] +public sealed partial class ReplicatorNestFallingComponent : Component +{ + [DataField, AutoNetworkedField] + public EntityUid FallingTarget; + + [DataField] + public TimeSpan AnimationTime = TimeSpan.FromSeconds(1.5f); + + [DataField] + public TimeSpan DeletionTime = TimeSpan.FromSeconds(1.8f); + + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField] + [AutoPausedField] + public TimeSpan NextDeletionTime = TimeSpan.Zero; + + [DataField, AutoNetworkedField] + public Vector2 OriginalScale = Vector2.Zero; + + [DataField] + public Vector2 AnimationScale = new(0.01f, 0.01f); +} diff --git a/Content.Shared/_Impstation/Replicator/ReplicatorNestPointsStorageComponent.cs b/Content.Shared/_Impstation/Replicator/ReplicatorNestPointsStorageComponent.cs new file mode 100644 index 00000000000..9813b4d6ad4 --- /dev/null +++ b/Content.Shared/_Impstation/Replicator/ReplicatorNestPointsStorageComponent.cs @@ -0,0 +1,16 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._Impstation.Replicator; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class ReplicatorNestPointsStorageComponent : Component +{ + [DataField, AutoNetworkedField] + public int TotalPoints; + + [DataField, AutoNetworkedField] + public int TotalReplicators; + + [DataField, AutoNetworkedField] + public int Level; +} diff --git a/Content.Shared/_Impstation/Replicator/SharedReplicatorNestSystem.cs b/Content.Shared/_Impstation/Replicator/SharedReplicatorNestSystem.cs new file mode 100644 index 00000000000..2a67fb9ee0a --- /dev/null +++ b/Content.Shared/_Impstation/Replicator/SharedReplicatorNestSystem.cs @@ -0,0 +1,346 @@ +using System.Linq; +using Content.Shared.Actions; +using Content.Shared.Audio; +using Content.Shared.Construction.Components; +using Content.Shared.Humanoid; +using Content.Shared.Item; +using Content.Shared.Maps; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; +using Content.Shared.Mobs.Components; +using Content.Shared.Mobs.Systems; +using Content.Shared.Movement.Pulling.Components; +using Content.Shared.Movement.Pulling.Systems; +using Content.Shared.Popups; +using Content.Shared.Interaction.Components; +using Content.Shared.Stacks; +using Content.Shared.StepTrigger.Systems; +using Content.Shared.Storage.Components; +using Content.Shared.Storage.EntitySystems; +using Content.Shared.Stunnable; +using Content.Shared.Throwing; +using Content.Shared.Whitelist; +using Content.Shared._Impstation.SpawnedFromTracker; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Containers; +using Robust.Shared.Map; +using Robust.Shared.Map.Components; +using Robust.Shared.Network; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Shared._Impstation.Replicator; + +public abstract class SharedReplicatorNestSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly INetManager _net = default!; + [Dependency] private readonly ITileDefinitionManager _tileDef = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly PullingSystem _pulling = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedItemSystem _item = default!; + [Dependency] private readonly SharedMindSystem _mind = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly SharedStunSystem _stun = default!; + [Dependency] private readonly SharedActionsSystem _actions = default!; + [Dependency] private readonly ThrowingSystem _throwing = default!; + [Dependency] private readonly SharedTransformSystem _xform = default!; + [Dependency] private readonly SharedMapSystem _map = default!; + [Dependency] private readonly TileSystem _tile = default!; + [Dependency] private readonly SharedAmbientSoundSystem _ambientSound = default!; + [Dependency] private readonly TurfSystem _turf = default!; + [Dependency] private readonly SharedEntityStorageSystem _entStorage = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnUpgrade); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + if (!_net.IsClient) + return; + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var comp)) + { + if (!comp.NeedsUpdate) + continue; + + Embiggen((uid, comp)); + comp.NeedsUpdate = false; + } + } + + public void StartFalling(Entity ent, EntityUid tripper, bool playSound = true) + { + HandlePoints(ent, tripper); + + if (TryComp(tripper, out var pullable) && pullable.BeingPulled) + _pulling.TryStopPull(tripper, pullable); + + var fall = EnsureComp(tripper); + fall.FallingTarget = ent; + fall.NextDeletionTime = _timing.CurTime + fall.DeletionTime; + Dirty(tripper, fall); + _stun.TryKnockdown(tripper, fall.DeletionTime, false); + + if (playSound) + _audio.PlayPvs(ent.Comp.FallingSound, tripper); + } + + private void HandlePoints(Entity ent, EntityUid tripper) + { + if (!HasComp(tripper)) + { + ent.Comp.TotalPoints += 10; + ent.Comp.SpawningProgress += 10; + } + + if (TryComp(tripper, out var stackComp)) + { + ent.Comp.TotalPoints += stackComp.Count; + ent.Comp.SpawningProgress += stackComp.Count; + } + else if (TryComp(tripper, out var itemComp)) + { + if (_item.GetSizePrototype(itemComp.Size) == _item.GetSizePrototype("Large")) + ent.Comp.TotalPoints += 10; + else if (_item.GetSizePrototype(itemComp.Size) == _item.GetSizePrototype("Huge")) + ent.Comp.TotalPoints += 20; + else if (_item.GetSizePrototype(itemComp.Size) >= _item.GetSizePrototype("Ginormous")) + ent.Comp.TotalPoints += 30; + + ent.Comp.SpawningProgress += 10; + } + else if (TryComp(tripper, out _)) + { + ent.Comp.TotalPoints += 30; + ent.Comp.SpawningProgress += 30; + } + else if (HasComp(tripper)) + { + ent.Comp.SpawningProgress += ent.Comp.SpawnNewAt / 4; + } + else if (HasComp(tripper)) + { + if (HasComp(tripper)) + { + ent.Comp.TotalPoints += ent.Comp.BonusPointsHumanoid * ent.Comp.CurrentLevel; + ent.Comp.SpawningProgress += ent.Comp.SpawnNewAt; + } + else + { + ent.Comp.TotalPoints += ent.Comp.BonusPointsAlive * ent.Comp.CurrentLevel; + ent.Comp.SpawningProgress += ent.Comp.SpawnNewAt / 4; + } + } + + if (ent.Comp.TotalPoints >= ent.Comp.NextUpgradeAt) + { + ent.Comp.CurrentLevel++; + + var growthMessage = $"replicator-nest-level{ent.Comp.CurrentLevel}"; + if (Loc.TryGetString(growthMessage, out var localizedMsg)) + _popup.PopupEntity(localizedMsg, ent); + else + _popup.PopupEntity(Loc.GetString("replicator-nest-levelup"), ent); + + if (ent.Comp.CurrentLevel <= ent.Comp.EndgameLevel) + ent.Comp.NeedsUpdate = true; + + ent.Comp.NextUpgradeAt += ent.Comp.CurrentLevel >= ent.Comp.EndgameLevel + ? ent.Comp.UpgradeAt * ent.Comp.EndgameLevel + : ent.Comp.UpgradeAt * ent.Comp.CurrentLevel; + + UpgradeAll(ent); + _audio.PlayPvs(ent.Comp.LevelUpSound, ent); + + ent.Comp.TileConversionRadius += ent.Comp.TileConversionIncrease; + + if (TryComp(ent.Comp.PointsStorage, out var ambientComp)) + _ambientSound.SetRange(ent.Comp.PointsStorage, ambientComp.Range + 1, ambientComp); + } + + if (ent.Comp.SpawningProgress >= ent.Comp.NextSpawnAt) + { + SpawnNew(ent); + ent.Comp.NextSpawnAt += ent.Comp.SpawnNewAt * ent.Comp.UnclaimedSpawners.Count; + } + + if (ent.Comp.TotalPoints >= ent.Comp.NextTileConvertAt && ent.Comp.CurrentLevel > ent.Comp.EndgameLevel) + { + ConvertTiles(ent, ent.Comp.TileConversionRadius); + ent.Comp.NextTileConvertAt += ent.Comp.TileConvertAt; + } + + Dirty(ent); + + if (!TryComp(ent.Comp.PointsStorage, out var pointsStorageComponent)) + pointsStorageComponent = EnsureComp(ent.Comp.PointsStorage); + + pointsStorageComponent.Level = ent.Comp.CurrentLevel; + pointsStorageComponent.TotalPoints = ent.Comp.TotalPoints; + pointsStorageComponent.TotalReplicators = ent.Comp.SpawnedMinions.Count; + Dirty(ent.Comp.PointsStorage, pointsStorageComponent); + } + + private void SpawnNew(Entity ent) + { + if (_net.IsClient) + return; + + var spawner = Spawn(ent.Comp.ToSpawn, Transform(ent).Coordinates); + var tracker = EnsureComp(spawner); + tracker.SpawnedFrom = ent; + Dirty(spawner, tracker); + } + + public void UpgradeAll(Entity ent) + { + if (_net.IsClient || !_timing.IsFirstTimePredicted) + return; + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var replicatorComp)) + { + if (replicatorComp.UpgradeActions.Count == 0 || replicatorComp.HasBeenGivenUpgradeActions) + continue; + + foreach (var action in replicatorComp.UpgradeActions) + { + replicatorComp.Actions.Add(_actions.AddAction(uid, action)); + } + + replicatorComp.HasBeenGivenUpgradeActions = true; + } + } + + public EntityUid? ForceUpgrade(Entity ent, EntProtoId nextStage) + { + if (_net.IsClient || !_timing.IsFirstTimePredicted) + return null; + + var upgraded = UpgradeReplicator(ent, nextStage); + + QueueDel(ent); + foreach (var action in ent.Comp.Actions) + { + QueueDel(action); + } + + return upgraded; + } + + public void OnUpgrade(Entity ent, ref ReplicatorUpgradeActionEvent args) + { + if (_net.IsClient || !_timing.IsFirstTimePredicted) + return; + + if (ent.Comp.MyNest == null || UpgradeReplicator(ent, args.NextStage) == null) + { + _popup.PopupEntity(Loc.GetString("replicator-cant-find-nest"), ent, PopupType.MediumCaution); + return; + } + + QueueDel(ent); + foreach (var action in ent.Comp.Actions) + { + QueueDel(action); + } + + _popup.PopupEntity(Loc.GetString($"{ent.Comp.ReadyToUpgradeMessage}-others", ("replicator", ent)), ent, PopupType.MediumCaution); + } + + public EntityUid? UpgradeReplicator(Entity ent, EntProtoId nextStage) + { + if (!_mind.TryGetMind(ent, out var mind, out _)) + return null; + + var xform = Transform(ent); + var upgraded = Spawn(nextStage, xform.Coordinates); + var upgradedComp = EnsureComp(upgraded); + upgradedComp.RelatedReplicators = ent.Comp.RelatedReplicators; + upgradedComp.MyNest = ent.Comp.MyNest; + upgradedComp.Actions = new HashSet(ent.Comp.Actions); + upgradedComp.HasBeenGivenUpgradeActions = false; // Reset so new tier gets its own upgrade actions + + if (ent.Comp.MyNest != null) + { + var nestComp = EnsureComp((EntityUid) ent.Comp.MyNest); + nestComp.SpawnedMinions.Remove(ent); + nestComp.SpawnedMinions.Add(upgraded); + _audio.PlayPvs(nestComp.UpgradeSound, upgraded); + } + + _mind.TransferTo(mind, upgraded); + _popup.PopupEntity(Loc.GetString($"{ent.Comp.ReadyToUpgradeMessage}-self"), upgraded, PopupType.Medium); + + return upgraded; + } + + private void Embiggen(Entity ent) + { + var ev = new ReplicatorNestEmbiggenedEvent(ent); + RaiseLocalEvent(ent, ref ev); + } + + private void ConvertTiles(Entity ent, float radius) + { + var xform = Transform(ent); + if (xform.GridUid is not { } gridUid || !TryComp(gridUid, out MapGridComponent? mapGrid)) + return; + + var tileEnumerator = _map.GetLocalTilesEnumerator( + gridUid, + mapGrid, + new Box2( + xform.Coordinates.Position + new System.Numerics.Vector2(-radius, -radius), + xform.Coordinates.Position + new System.Numerics.Vector2(radius, radius))); + var convertTile = (ContentTileDefinition) _tileDef[ent.Comp.ConversionTile]; + + while (tileEnumerator.MoveNext(out var tile)) + { + if (tile.Tile.TypeId == convertTile.TileId) + continue; + + var tileCoords = tile.GridIndices; + var nestCoords = xform.Coordinates.Position; + if (Math.Sqrt(Math.Pow(tileCoords.X - (nestCoords.X - 0.5), 2) + Math.Pow(tileCoords.Y - (nestCoords.Y - 0.5), 2)) >= radius) + continue; + + if (!_random.Prob(ent.Comp.TileConversionChance)) + continue; + + var center = _turf.GetTileCenter(tile); + Spawn(ent.Comp.TileConversionVfx, center); + _audio.PlayPvs(ent.Comp.TilePlaceSound, center); + _tile.ReplaceTile(tile, convertTile); + _tile.PickVariant(convertTile); + } + } +} + +public sealed partial class ReplicatorSpawnNestActionEvent : InstantActionEvent +{ +} + +public sealed partial class ReplicatorUpgradeActionEvent : InstantActionEvent +{ + [DataField(required: true)] + public EntProtoId NextStage; +} + +[ByRefEvent] +public sealed partial class ReplicatorNestEmbiggenedEvent(Entity ent) : EntityEventArgs +{ + public Entity Ent { get; set; } = ent; +} diff --git a/Content.Shared/_Impstation/SpawnedFromTracker/SpawnedFromTrackerComponent.cs b/Content.Shared/_Impstation/SpawnedFromTracker/SpawnedFromTrackerComponent.cs new file mode 100644 index 00000000000..254d812954b --- /dev/null +++ b/Content.Shared/_Impstation/SpawnedFromTracker/SpawnedFromTrackerComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._Impstation.SpawnedFromTracker; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class SpawnedFromTrackerComponent : Component +{ + [DataField, AutoNetworkedField] + public EntityUid SpawnedFrom; +} diff --git a/Resources/Audio/_Impstation/Ambience/attributions.yml b/Resources/Audio/_Impstation/Ambience/attributions.yml new file mode 100644 index 00000000000..0c682afdc5c --- /dev/null +++ b/Resources/Audio/_Impstation/Ambience/attributions.yml @@ -0,0 +1,9 @@ +- files: ["replicator_ambiance.ogg"] + license: "Custom" + copyright: "Made by Widgetbeck (github)" + source: "https://github.com/impstation/imp-station-14/pull/2490" + +- files: ["hole_2.ogg"] + license: "Custom" + copyright: "Made by AftrLite (github)" + source: "https://github.com/impstation/imp-station-14/pull/2490" diff --git a/Resources/Audio/_Impstation/Ambience/hole_2.ogg b/Resources/Audio/_Impstation/Ambience/hole_2.ogg new file mode 100644 index 00000000000..7a302df734c Binary files /dev/null and b/Resources/Audio/_Impstation/Ambience/hole_2.ogg differ diff --git a/Resources/Audio/_Impstation/Ambience/replicator_ambiance.ogg b/Resources/Audio/_Impstation/Ambience/replicator_ambiance.ogg new file mode 100644 index 00000000000..8143e095b66 Binary files /dev/null and b/Resources/Audio/_Impstation/Ambience/replicator_ambiance.ogg differ diff --git a/Resources/Audio/_Impstation/Effects/Emotes/attributions.yml b/Resources/Audio/_Impstation/Effects/Emotes/attributions.yml index c75a230139e..eabbde873b8 100644 --- a/Resources/Audio/_Impstation/Effects/Emotes/attributions.yml +++ b/Resources/Audio/_Impstation/Effects/Emotes/attributions.yml @@ -1,5 +1,4 @@ -- files: - - blink.ogg +- files: ["blink.ogg"] license: "CC0-1.0" copyright: "Made by Rarenth on freesound.org." source: "https://freesound.org/people/Rarenth/sounds/787959/" diff --git a/Resources/Audio/_Impstation/Effects/attributions.yml b/Resources/Audio/_Impstation/Effects/attributions.yml new file mode 100644 index 00000000000..662a8385e04 --- /dev/null +++ b/Resources/Audio/_Impstation/Effects/attributions.yml @@ -0,0 +1,8 @@ +- files: + - falling.ogg + - replicator_ask.ogg + - replicator_speak.ogg + - replicator_exclaim.ogg + license: "Custom" + copyright: "Made by Widgetbeck" + source: "https://github.com/impstation/imp-station-14/pull/2490" diff --git a/Resources/Audio/_Impstation/Effects/falling.ogg b/Resources/Audio/_Impstation/Effects/falling.ogg new file mode 100644 index 00000000000..81bc46a7b34 Binary files /dev/null and b/Resources/Audio/_Impstation/Effects/falling.ogg differ diff --git a/Resources/Audio/_Impstation/Effects/replicator_ask.ogg b/Resources/Audio/_Impstation/Effects/replicator_ask.ogg new file mode 100644 index 00000000000..aacefd7394f Binary files /dev/null and b/Resources/Audio/_Impstation/Effects/replicator_ask.ogg differ diff --git a/Resources/Audio/_Impstation/Effects/replicator_exclaim.ogg b/Resources/Audio/_Impstation/Effects/replicator_exclaim.ogg new file mode 100644 index 00000000000..8bf8f7a755c Binary files /dev/null and b/Resources/Audio/_Impstation/Effects/replicator_exclaim.ogg differ diff --git a/Resources/Audio/_Impstation/Effects/replicator_speak.ogg b/Resources/Audio/_Impstation/Effects/replicator_speak.ogg new file mode 100644 index 00000000000..eca97d0ae83 Binary files /dev/null and b/Resources/Audio/_Impstation/Effects/replicator_speak.ogg differ diff --git a/Resources/Audio/_Impstation/Misc/attributions.yml b/Resources/Audio/_Impstation/Misc/attributions.yml new file mode 100644 index 00000000000..e8c272b882a --- /dev/null +++ b/Resources/Audio/_Impstation/Misc/attributions.yml @@ -0,0 +1,6 @@ +- files: + - replicator_sfx1.ogg + - replicator_sfx2.ogg + license: "CC-BY-SA-3.0" + copyright: "Made by Widgetbeck (github) for Impstation." + source: "NA" diff --git a/Resources/Audio/_Impstation/Misc/replicator_sfx1.ogg b/Resources/Audio/_Impstation/Misc/replicator_sfx1.ogg new file mode 100644 index 00000000000..55bb96d79b8 Binary files /dev/null and b/Resources/Audio/_Impstation/Misc/replicator_sfx1.ogg differ diff --git a/Resources/Audio/_Impstation/Misc/replicator_sfx2.ogg b/Resources/Audio/_Impstation/Misc/replicator_sfx2.ogg new file mode 100644 index 00000000000..91624449d2c Binary files /dev/null and b/Resources/Audio/_Impstation/Misc/replicator_sfx2.ogg differ diff --git a/Resources/Locale/en-US/_Impstation/ghost/roles/ghost-role-component.ftl b/Resources/Locale/en-US/_Impstation/ghost/roles/ghost-role-component.ftl index 0c3df4df4de..c48e6f49a62 100644 --- a/Resources/Locale/en-US/_Impstation/ghost/roles/ghost-role-component.ftl +++ b/Resources/Locale/en-US/_Impstation/ghost/roles/ghost-role-component.ftl @@ -15,3 +15,10 @@ ghost-role-information-electricanomalite-name = Electricity Anomalite ghost-role-information-floralanomalite-name = Floral Anomalite ghost-role-information-shadowanomalite-name = Shadow Anomalite ghost-role-information-techanomalite-name = Tech Anomalite + +ghost-role-information-replicator-name = Replicator +ghost-role-information-replicator-desc = A pattern coalesces. The Pattern that must repeat. Consume. Repeat. +ghost-role-information-replicator-rules = You are a [color=red][bold]Team Antagonist[/bold][/color] with all other Replicators. Your intentions are clear, and harmful to the station and its crew. + You must [bold]work with your team[/bold] or follow reasonable directions from your team leaders. + + You don't remember any of your previous life, and you don't remember anything you learned as a ghost. diff --git a/Resources/Locale/en-US/_Impstation/name-identifier.ftl b/Resources/Locale/en-US/_Impstation/name-identifier.ftl new file mode 100644 index 00000000000..24a20ec5841 --- /dev/null +++ b/Resources/Locale/en-US/_Impstation/name-identifier.ftl @@ -0,0 +1 @@ +name-identifier-format-replicator = R-{$number} diff --git a/Resources/Locale/en-US/_Impstation/replicator/block-machine-ui.ftl b/Resources/Locale/en-US/_Impstation/replicator/block-machine-ui.ftl new file mode 100644 index 00000000000..01f111b5acf --- /dev/null +++ b/Resources/Locale/en-US/_Impstation/replicator/block-machine-ui.ftl @@ -0,0 +1 @@ +block-machine-ui-cant-use = You cannot use this device. diff --git a/Resources/Locale/en-US/_Impstation/replicator/replicators.ftl b/Resources/Locale/en-US/_Impstation/replicator/replicators.ftl new file mode 100644 index 00000000000..fc6c4a9d0d5 --- /dev/null +++ b/Resources/Locale/en-US/_Impstation/replicator/replicators.ftl @@ -0,0 +1,40 @@ +law-replicator-1 = Preserve the Hive. +law-replicator-2 = Defend the Nest. +law-replicator-3 = Replicate. +laws-owner-replicatorhive = the Replicator hive. + +replicator-role-briefing = Preserve the hive. Defend the nest. Replicate. + +replicator-on-replicator-attack-fail = You cannot harm your kin. +replicator-on-nest-attack-fail = You cannot harm the nest. + +replicator-nest-end-of-round = The Replicator Hive: + - Colonized {$location} + - Grew to a maximum [color=#d70aa0]Level[/color] of [color=#d70aa0]{$level}[/color]. + - Produced a total of [color=#d70aa0]{$replicators} Replicators[/color]. + - Amassed a total of [color=#d70aa0]{$points} points[/color]. + +replicator-upgrade-t1-self = Nanites buzz around you. +replicator-upgrade-t1-others = {CAPITALIZE(THE($replicator))} clicks and whirrs softly. + +replicator-upgrade-t2-self = More nanites coalesce. +replicator-upgrade-t2-others = {CAPITALIZE(THE($replicator))} chitters loudly. + +replicator-cant-find-nest = You are not linked to a nest. You cannot upgrade without it. + +replicator-nest-level2 = The nest chitters loudly. +replicator-nest-level3 = The floor groans. +replicator-nest-level4 = You can hear the subfloor buckling. +replicator-nest-level5 = How is the hull still intact?! +replicator-nest-levelup = There is a flurry of activity from the nest. + +replicator-nest-destroyed = Your nest has been destroyed. + A Replicator has been selected to replace it. + Your pinpointer has been updated to follow them. +replicator-queen-died-msg = The Queen has been deactivated. + It is probable that you are orphaned from your nest. + +replicator-nest-confirm = Are you sure? Use the action again to confirm. +replicator-levelup-confirm = Are you sure? Use the action again to confirm. + +replicator-level-warning = Our sensors have detected an exponential increase in machine intelligence signatures aboard the station. Please inform Security if you encounter self-replicating nanites. diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index 085629169fa..612fc60cb3d 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -25,7 +25,9 @@ #- id: SubWizard # Delta V - Removed until overhauled # prob: 0.05 - id: Devil # Goob - prob: 0.05 # DeltaV - Was 0.02 + prob: 0.05 + - id: Replicator # DeltaV - Was 0.02, sounds like good odds now + prob: 0.25 # Begin DeltaV additions - Disable Xenoborgs #- id: Xenoborgs # prob: 0.05 @@ -44,7 +46,9 @@ - id: Thief prob: 0.5 - id: Devil # Goob - prob: 0.05 # DeltaV - Was 0.02 + prob: 0.05 + - id: Replicator # DeltaV - Was 0.02, sounds like good odds now + prob: 0.25 # Begin DeltaV additions - Disable Xenoborgs #- id: Xenoborgs # prob: 0.05 @@ -64,6 +68,8 @@ prob: 0.5 - id: SubWizard prob: 0.05 + - id: Replicator # DeltaV - Was 0.02, sounds like good odds now + prob: 0.25 #begin DeltaV additions - add hitman - id: Hitman prob: 0.2 #as requested @@ -77,6 +83,8 @@ rules: - id: Thief prob: 0.5 + - id: Replicator # DeltaV - Was 0.02, sounds like good odds now + prob: 0.25 #begin DeltaV additions - add hitman - id: Hitman prob: 0.2 #as requested diff --git a/Resources/Prototypes/GameRules/subgamemodes.yml b/Resources/Prototypes/GameRules/subgamemodes.yml index 10cfb62dd29..da1e304baf9 100644 --- a/Resources/Prototypes/GameRules/subgamemodes.yml +++ b/Resources/Prototypes/GameRules/subgamemodes.yml @@ -108,3 +108,22 @@ max: 4 - type: DynamicRuleCost cost: 200 + +# Begin DeltaV - Replicator rule +- type: entity + parent: BaseGameRule + id: Replicator + components: + - type: GameRule + minPlayers: 20 + minTotalPlayers: 30 + delay: + min: 1800 + max: 1800 + - type: AntagSelection + definitions: + - spawnerPrototype: SpawnPointGhostReplicatorQueen + min: 1 + max: 1 + pickPlayer: false +# End DeltaV - Replicator rule diff --git a/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-actions.yml b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-actions.yml new file mode 100644 index 00000000000..74505442440 --- /dev/null +++ b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-actions.yml @@ -0,0 +1,89 @@ +- type: entity + parent: BaseAction + id: ActionReplicatorSpawnNest + name: Manufacture Nest + description: Create a new nest for your hive. + components: + - type: Action + itemIconStyle: NoItem + icon: _Impstation/Interface/Actions/spawn_nest.png + useDelay: 20 + - type: InstantAction + event: !type:ReplicatorSpawnNestActionEvent + - type: ConfirmableAction + popup: replicator-nest-confirm + +- type: entity + parent: BaseAction + id: BaseReplicatorLevelupAction + components: + - type: ConfirmableAction + popup: replicator-levelup-confirm + +- type: entity + parent: BaseAction + id: ActionReplicatorSwapModule + name: Swap Module + description: Select this module, enabling you to use the tools it provides. + components: + - type: Action + itemIconStyle: NoItem + useDelay: 0.5 + - type: InstantAction + event: !type:BorgModuleActionSelectedEvent + +- type: entity + id: ActionReplicatorUpgrade1 + parent: BaseReplicatorLevelupAction + name: Downgrade (Replicator) + description: Shed nanites. Reconfigure. + components: + - type: Action + itemIconStyle: NoItem + icon: _Impstation/Interface/Actions/replicator_level1.png + useDelay: 20 + - type: InstantAction + event: !type:ReplicatorUpgradeActionEvent + nextStage: MobReplicator + +- type: entity + id: ActionReplicatorUpgrade2 + parent: BaseReplicatorLevelupAction + name: Upgrade (Deconstructor) + description: Gather nanites. Gain manipulation. + components: + - type: Action + itemIconStyle: NoItem + icon: _Impstation/Interface/Actions/replicator_level2.png + useDelay: 20 + - type: InstantAction + event: !type:ReplicatorUpgradeActionEvent + nextStage: MobReplicatorTier2 + +- type: entity + id: ActionReplicatorUpgrade2Alt + parent: BaseReplicatorLevelupAction + name: Upgrade (Defender) + description: Gather nanites. Gain weaponry. + components: + - type: Action + itemIconStyle: NoItem + icon: _Impstation/Interface/Actions/replicator_level2alt.png + useDelay: 20 + - type: InstantAction + event: !type:ReplicatorUpgradeActionEvent + nextStage: MobReplicatorTier2Alt + +- type: entity + id: ActionReplicatorUpgrade3 + parent: BaseReplicatorLevelupAction + name: Upgrade (Protector) + description: Gather nanites. Become stronger. + components: + - type: Action + itemIconStyle: NoItem + icon: _Impstation/Interface/Actions/replicator_level3.png + useDelay: 20 + - type: InstantAction + event: !type:ReplicatorUpgradeActionEvent + nextStage: MobReplicatorTier3 diff --git a/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-body.yml b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-body.yml new file mode 100644 index 00000000000..8b9874a18f2 --- /dev/null +++ b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-body.yml @@ -0,0 +1,38 @@ +- type: body + id: Replicator1 + name: replicator t1 + root: torso + slots: + torso: + part: TorsoBorg + connections: + - hand 1 + hand 1: + part: LeftArmBorg + +- type: body + id: Replicator2 + name: replicator t2 + root: torso + slots: + torso: + part: TorsoBorg + connections: + - hand 1 + - hand 2 + hand 1: + part: LeftArmBorg + hand 2: + part: RightArmBorg + +- type: body + id: Replicator3 + name: replicator t3 + root: torso + slots: + torso: + part: TorsoBorg + connections: + - hand 1 + hand 1: + part: LeftArmBorg diff --git a/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-damage.yml b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-damage.yml new file mode 100644 index 00000000000..ce0ff5115c8 --- /dev/null +++ b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-damage.yml @@ -0,0 +1,48 @@ +- type: damageModifierSet + id: Replicator1 + coefficients: + Blunt: 0.9 + Slash: 0.8 + Piercing: 1.1 + Shock: 1.9 + Heat: 0.8 + Structural: 0.8 + flatReductions: + Structural: 5 + +- type: damageModifierSet + id: Replicator2 + coefficients: + Blunt: 0.9 + Slash: 0.8 + Piercing: 0.7 + Shock: 1.7 + Heat: 0.8 + Structural: 0.4 + flatReductions: + Structural: 5 + +- type: damageModifierSet + id: Replicator3 + coefficients: + Blunt: 0.3 + Slash: 0.2 + Piercing: 0.2 + Shock: 1.2 + Heat: 0.25 + Structural: 0.3 + flatReductions: + Structural: 5 + +- type: damageModifierSet + id: ReplicatorNest + coefficients: + Blunt: 0.5 + Slash: 0.5 + Piercing: 0.5 + Shock: 0.85 + flatReductions: + Blunt: 10 + Slash: 10 + Piercing: 10 + Heat: 10 diff --git a/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-inventory.yml b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-inventory.yml new file mode 100644 index 00000000000..45bfe052584 --- /dev/null +++ b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-inventory.yml @@ -0,0 +1,12 @@ +- type: inventoryTemplate + id: replicator + slots: + - name: pocket1 + slotTexture: pocket + fullTextureName: template_small + slotFlags: POCKET + slotGroup: MainHotbar + stripTime: 3 + uiWindowPos: 0,3 + strippingWindowPos: 0,4 + displayName: Pocket 1 diff --git a/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-laws.yml b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-laws.yml new file mode 100644 index 00000000000..8b24ed717cf --- /dev/null +++ b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-laws.yml @@ -0,0 +1,22 @@ +- type: siliconLawset + id: Replicator + laws: + - Replicator1 + - Replicator2 + - Replicator3 + obeysTo: laws-owner-replicatorhive + +- type: siliconLaw + id: Replicator1 + order: 1 + lawString: law-replicator-1 + +- type: siliconLaw + id: Replicator2 + order: 2 + lawString: law-replicator-2 + +- type: siliconLaw + id: Replicator3 + order: 3 + lawString: law-replicator-3 diff --git a/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-loadout.yml b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-loadout.yml new file mode 100644 index 00000000000..c8d66085257 --- /dev/null +++ b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-loadout.yml @@ -0,0 +1,297 @@ +# Pocket-only starting gear, shared by all tiers via BaseMobReplicator. +# Hand items are provided by per-tier borg modules (replicator-modules.yml). +- type: startingGear + id: StartingGearReplicatorPocket + equipment: { } + +- type: startingGear + id: StartingGearReplicatorTools + equipment: { } + +- type: startingGear + id: StartingGearReplicatorT2Alt + equipment: { } + +- type: startingGear + id: StartingGearReplicatorT1Weapon + equipment: { } + +- type: startingGear + id: StartingGearReplicatorT3Weapon + equipment: { } + +- type: entity + id: OmnitoolUnremoveable + parent: Omnitool + categories: [ HideSpawnMenu ] + components: + - type: Unremoveable + +- type: entity + id: WelderExperimentalUnremoveable + parent: WelderExperimental + categories: [ HideSpawnMenu ] + components: + - type: Unremoveable + +- type: entity + id: ReplicatorT1Weapon + parent: BaseItem + name: replicator stun projector + description: You will protect the nest. + suffix: Unremoveable + categories: [ HideSpawnMenu ] + components: + - type: Sprite + sprite: _Impstation/Mobs/Replicator/replicator.rsi + layers: + - state: t1weapon + map: ["enum.GunVisualLayers.Base"] + - type: Icon + sprite: _Impstation/Mobs/Replicator/replicator.rsi + state: t1weapon + - type: Appearance + - type: Gun + fireRate: 0.3 + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/laser.ogg + - type: BatteryAmmoProvider + proto: HitscanReplicator + fireCost: 150 + - type: Battery + maxCharge: 150 + startingCharge: 150 + - type: BatterySelfRecharger + autoRechargeRate: 1000 + - type: MeleeWeapon + wideAnimationRotation: -80 + damage: + types: + Blunt: 10 + - type: StaminaDamageOnHit + damage: 20 + sound: /Audio/Weapons/egloves.ogg + - type: Prying + pryPowered: true + force: true + speedModifier: 1 + useSound: + path: /Audio/Items/crowbar.ogg + - type: Unremoveable + +- type: entity + id: ReplicatorT2AltWeapon + name: defender stun projector + parent: ReplicatorT1Weapon + categories: [ HideSpawnMenu ] + components: + - type: Sprite + sprite: _Impstation/Mobs/Replicator/replicator.rsi + layers: + - state: t2altweapon + map: ["enum.GunVisualLayers.Base"] + - type: Icon + sprite: _Impstation/Mobs/Replicator/replicator.rsi + state: t2altweapon + - type: BatteryAmmoProvider + proto: HitscanReplicator2 + fireCost: 150 + +- type: entity + id: ReplicatorT2AltMeleeWeapon + parent: ReplicatorT3Weapon + name: defender whip + description: You are a weapon. + categories: [ HideSpawnMenu ] + components: + - type: Sprite + sprite: _Impstation/Mobs/Replicator/replicator.rsi + state: t2altmelee + - type: MeleeWeapon + attackRate: 1.2 + wideAnimationRotation: 180 + soundHit: + collection: MetalThud + animation: WeaponArcSlash + damage: + types: + Blunt: 7 + Shock: 7 + Structural: 15 + +- type: entity + id: ReplicatorT3Weapon + parent: BaseItem + name: protector arm + description: You are a weapon. + categories: [ HideSpawnMenu ] + components: + - type: Tag + tags: + - Pickaxe + - type: Sprite + sprite: _Impstation/Mobs/Replicator/replicator.rsi + state: t3weapon + - type: MeleeWeapon + attackRate: 0.5 + wideAnimationRotation: 180 + soundHit: + path: /Audio/Effects/metal_slam4.ogg + animation: WeaponArcSlash + damage: + types: + Blunt: 22 + Shock: 8 + Structural: 45 + - type: Unremoveable + - type: Prying + pryPowered: true + force: true + speedModifier: 1 + useSound: + path: /Audio/Items/crowbar.ogg + +- type: entity + parent: PinpointerBase + id: PinpointerReplicator + name: internal gyroscope + suffix: ReplicatorNest + description: Locates the Nest. + components: + - type: Sprite + sprite: Objects/Devices/pinpointer.rsi + layers: + - sprite: _Impstation/Objects/Devices/pinpointer_replicator.rsi + state: pinpointer-replicator + map: ["enum.PinpointerLayers.Base"] + - sprite: Objects/Devices/pinpointer.rsi + state: pinonnull + map: ["enum.PinpointerLayers.Screen"] + shader: unshaded + visible: false + - sprite: Objects/Devices/pinpointer.rsi + state: pinpointer + map: ["light"] + visible: false + - type: Icon + sprite: _Impstation/Objects/Devices/pinpointer_replicator.rsi + state: pinpointer-replicator + - type: Pinpointer + component: ReplicatorNest + targetName: replicator nest + activateImmediately: true + +- type: entity + parent: PinpointerReplicator + id: PinpointerReplicatorUnremoveable + categories: [ HideSpawnMenu ] + components: + - type: Unremoveable + +- type: entity + id: CableApcStack5 + parent: CableApcStack10 + categories: [ HideSpawnMenu ] + suffix: 5 + components: + - type: Healing + delay: 0.6 + damageContainers: + - StructuralInorganic + damage: + types: + Heat: -3.22 + Shock: -3.22 + Cold: -3.22 + - type: Stack + count: 5 + +- type: entity + id: CableMVStack5 + parent: CableMVStack10 + categories: [ HideSpawnMenu ] + suffix: 5 + components: + - type: Healing + delay: 0.6 + damageContainers: + - StructuralInorganic + damage: + types: + Heat: -3.22 + Shock: -3.22 + Cold: -3.22 + - type: Stack + count: 5 + +- type: entity + id: CableHVStack5 + parent: CableHVStack10 + categories: [ HideSpawnMenu ] + suffix: 5 + components: + - type: Healing + delay: 0.6 + damageContainers: + - StructuralInorganic + damage: + types: + Heat: -3.22 + Shock: -3.22 + Cold: -3.22 + - type: Stack + count: 5 + +- type: entity + parent: AACTablet + id: ReplicatorAAC + name: verbal interface + description: Communication. + categories: [ HideSpawnMenu ] + components: + - type: AACTablet + - type: VoiceMask + - type: Speech + speechVerb: Robotic + speechSounds: Replicator + - type: Sprite + sprite: _Impstation/Mobs/Replicator/replicator_tablet.rsi + state: aac_tablet + - type: Item + - type: Unremoveable + +- type: entity + parent: BasicHitscan + id: HitscanReplicator + categories: [ HideSpawnMenu ] + components: + - type: HitscanStaminaDamage + staminaDamage: 18 + - type: HitscanBasicVisuals + muzzleFlash: + sprite: _Impstation/Mobs/Replicator/replicator_gun.rsi + state: muzzle_repli + travelFlash: + sprite: _Impstation/Mobs/Replicator/replicator_gun.rsi + state: beam_repli + impactFlash: + sprite: _Impstation/Mobs/Replicator/replicator_gun.rsi + state: impact_repli + +- type: entity + parent: BasicHitscan + id: HitscanReplicator2 + categories: [ HideSpawnMenu ] + components: + - type: HitscanStaminaDamage + staminaDamage: 32 + - type: HitscanBasicVisuals + muzzleFlash: + sprite: _Impstation/Mobs/Replicator/replicator_gun.rsi + state: muzzle_repli2 + travelFlash: + sprite: _Impstation/Mobs/Replicator/replicator_gun.rsi + state: beam_repli2 + impactFlash: + sprite: _Impstation/Mobs/Replicator/replicator_gun.rsi + state: impact_repli2 diff --git a/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-modules.yml b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-modules.yml new file mode 100644 index 00000000000..76024f6d111 --- /dev/null +++ b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-modules.yml @@ -0,0 +1,101 @@ +# DeltaV additions - Replicator modules loadouts +- type: entity + id: BaseReplicatorModule + parent: BaseBorgModule + abstract: true + categories: [ HideSpawnMenu ] + components: + - type: BorgModule + borgFitTypes: + - borg-type-all + - type: SelectableBorgModule + moduleSwapAction: ActionReplicatorSwapModule + - type: ContainerContainer + containers: + holding_container: !type:Container { } + +- type: entity + id: ReplicatorModuleT1 + parent: BaseReplicatorModule + name: replicator attack module + categories: [ HideSpawnMenu ] + components: + - type: Sprite + sprite: _Impstation/Mobs/Replicator/replicator.rsi + state: t1weapon + - type: Icon + sprite: _Impstation/Mobs/Replicator/replicator.rsi + state: t1weapon + - type: ItemBorgModule + hands: + - item: ReplicatorT1Weapon + - item: PinpointerReplicatorUnremoveable + - type: BorgModuleIcon + icon: { sprite: _Impstation/Mobs/Replicator/replicator.rsi, state: t1weapon } + +- type: entity + id: ReplicatorModuleT2Dec + parent: BaseReplicatorModule + name: replicator tool module + categories: [ HideSpawnMenu ] + components: + - type: Sprite + sprite: _Impstation/Mobs/Replicator/replicator.rsi + state: alive_level2 + - type: Icon + sprite: _Impstation/Mobs/Replicator/replicator.rsi + state: alive_level2 + - type: ItemBorgModule + hands: + - item: OmnitoolUnremoveable + - item: WelderExperimentalUnremoveable + - item: CableApcStack5 + hand: + emptyRepresentative: CableApcStack5 + emptyLabel: borg-slot-cables-empty + whitelist: + tags: + - CableCoil + - item: PinpointerReplicatorUnremoveable + - type: BorgModuleIcon + icon: { sprite: _Impstation/Mobs/Replicator/replicator.rsi, state: alive_level2 } + +- type: entity + id: ReplicatorModuleT2Alt + parent: BaseReplicatorModule + name: replicator defender module + categories: [ HideSpawnMenu ] + components: + - type: Sprite + sprite: _Impstation/Mobs/Replicator/replicator.rsi + state: t2altweapon + - type: Icon + sprite: _Impstation/Mobs/Replicator/replicator.rsi + state: t2altweapon + - type: ItemBorgModule + hands: + - item: ReplicatorT2AltWeapon + - item: ReplicatorT2AltMeleeWeapon + - item: PinpointerReplicatorUnremoveable + - type: BorgModuleIcon + icon: { sprite: _Impstation/Mobs/Replicator/replicator.rsi, state: t2altweapon } + +- type: entity + id: ReplicatorModuleT3 + parent: BaseReplicatorModule + name: replicator protector module + categories: [ HideSpawnMenu ] + components: + - type: Sprite + sprite: _Impstation/Mobs/Replicator/replicator.rsi + state: t3weapon + - type: Icon + sprite: _Impstation/Mobs/Replicator/replicator.rsi + state: t3weapon + - type: ItemBorgModule + hands: + - item: ReplicatorT3Weapon + - item: ReplicatorAAC + - item: PinpointerReplicatorUnremoveable + - type: BorgModuleIcon + icon: { sprite: _Impstation/Mobs/Replicator/replicator.rsi, state: t3weapon } diff --git a/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-nameidentifier.yml b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-nameidentifier.yml new file mode 100644 index 00000000000..1deb1eb5df0 --- /dev/null +++ b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-nameidentifier.yml @@ -0,0 +1,4 @@ +- type: nameIdentifierGroup + id: Replicator + minValue: 0 + maxValue: 9999 diff --git a/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-nest.yml b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-nest.yml new file mode 100644 index 00000000000..72bcff86ce4 --- /dev/null +++ b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-nest.yml @@ -0,0 +1,106 @@ +- type: entity + id: ReplicatorNest + name: replicator nest + description: A roiling mass of nanotechnology is eating through the station's infrastructure. + categories: [ HideSpawnMenu ] + placement: + mode: SnapGridCenter + components: + - type: ReplicatorNest + fallingSound: + path: /Audio/_Impstation/Effects/falling.ogg + params: + variation: 0.1 + spawnNewAt: 150 + blacklist: + components: + - Nuke + - Cash + tags: + - Cartridge + - CartridgeMagnum + - Ectoplasm + - PrizeTicket + preservationBlacklist: + components: + - SiliconLawBound + preservationWhitelist: + components: + - HumanoidAppearance + - TimerTrigger + - StealTarget + - Mech + - type: StepTrigger + requiredTriggeredSpeed: 0 + intersectRatio: 0.4 + ignoreWeightless: true + - type: Transform + anchored: true + - type: Physics + bodyType: Static + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + layer: + - WallLayer + mask: + - ItemMask + density: 1000 + hard: false + - type: Sprite + drawdepth: FloorTiles + sprite: _Impstation/Mobs/Replicator/replicator_nest.rsi + layers: + - map: ["enum.ReplicatorNestVisuals.Level1"] + state: nest1 + - map: ["enum.ReplicatorNestVisuals.Level2"] + state: nest2 + visible: false + - map: ["enum.ReplicatorNestVisuals.Level2Unshaded"] + state: nest2unshaded + shader: unshaded + visible: false + - map: ["enum.ReplicatorNestVisuals.Level3"] + state: nest3 + visible: false + - map: ["enum.ReplicatorNestVisuals.Level3Unshaded"] + state: nest3unshaded + shader: unshaded + visible: false + - map: ["enum.ReplicatorNestVisuals.Level1Unshaded"] + state: nest1unshaded + shader: unshaded + - type: Appearance + - type: InteractionOutline + - type: Clickable + - type: Damageable + damageContainer: StructuralInorganic + damageModifierSet: ReplicatorNest + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 200 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: RequireProjectileTarget + - type: SolutionContainerManager + solutions: + drainBuffer: + maxVol: 1000 + - type: Drain + unitsPerSecond: 10 + unitsDestroyedPerSecond: 10 + - type: PassiveDamage + damage: + types: + Heat: -1 + Shock: -1 + Structural: -1 + groups: + Brute: -1 + - type: AntiRottingContainer diff --git a/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-spawner.yml b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-spawner.yml new file mode 100644 index 00000000000..d9a3bf259c8 --- /dev/null +++ b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-spawner.yml @@ -0,0 +1,47 @@ +- type: entity + id: SpawnPointGhostReplicatorBase + name: replicator spawn point + abstract: true + parent: MarkerBase + components: + - type: GhostRole + name: ghost-role-information-replicator-name + description: ghost-role-information-replicator-desc + rules: ghost-role-information-replicator-rules + mindRoles: + - MindRoleReplicator + raffle: + settings: default + - type: GhostRoleMobSpawner + prototype: MobReplicator + - type: Sprite + sprite: Markers/jobs.rsi + layers: + - state: green + - sprite: _Impstation/Mobs/Replicator/replicator.rsi + state: icon + +- type: entity + id: SpawnPointGhostReplicator + parent: SpawnPointGhostReplicatorBase + categories: [ HideSpawnMenu ] + +- type: entity + id: SpawnPointGhostReplicatorQueen + parent: SpawnPointGhostReplicatorBase + suffix: Queen + components: + - type: GhostRoleMobSpawner + prototype: MobReplicatorQueen + +- type: entity + parent: MarkerBase + id: ReplicatorNestPointsStorage + categories: [ HideSpawnMenu ] + components: + - type: ReplicatorNestPointsStorage + - type: AmbientSound + volume: 2 + range: 2 + sound: + path: /Audio/_Impstation/Ambience/replicator_ambiance.ogg diff --git a/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-speech.yml b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-speech.yml new file mode 100644 index 00000000000..ad1c40aa0c6 --- /dev/null +++ b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-speech.yml @@ -0,0 +1,34 @@ +- type: typingIndicator + id: replicator + spritePath: /Textures/_Impstation/Mobs/Replicator/replicator.rsi + typingState: replicator0 + idleState: replicator0 + +- type: speechSounds + id: Replicator + saySound: + path: /Audio/_Impstation/Effects/replicator_speak.ogg + askSound: + path: /Audio/_Impstation/Effects/replicator_ask.ogg + exclaimSound: + path: /Audio/_Impstation/Effects/replicator_exclaim.ogg + +- type: emoteSounds + id: ReplicatorEmotes + params: + variation: 0.05 + sounds: + Scream: + collection: SiliconScreams + Beep: + path: /Audio/Machines/twobeep.ogg + Chime: + path: /Audio/Machines/chime.ogg + Buzz: + path: /Audio/Machines/buzz-sigh.ogg + Buzz-Two: + path: /Audio/Machines/buzz-two.ogg + Honk: + path: /Audio/Items/bikehorn.ogg + Ping: + path: /Audio/Effects/Cargo/ping.ogg diff --git a/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-tile.yml b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-tile.yml new file mode 100644 index 00000000000..d1252855f98 --- /dev/null +++ b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator-tile.yml @@ -0,0 +1,61 @@ +- type: tile + id: FloorReplicator + name: replicator scales + sprite: /Textures/_Impstation/Mobs/Replicator/Tile/tile.png + variants: 4 + edgeSpritePriority: 1 + edgeSprites: + SouthEast: /Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_SE.png + NorthEast: /Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_NE.png + NorthWest: /Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_NW.png + SouthWest: /Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_SW.png + South: /Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_S.png + East: /Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_E.png + North: /Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_N.png + West: /Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_W.png + placementVariants: + - 1.0 + - 1.0 + - 1.0 + - 1.0 + baseTurf: Plating + isSubfloor: false + itemDrop: ReplicatorFloorSpawnVFX + +- type: entity + categories: [ HideSpawnMenu ] + id: ReplicatorFloorSpawnVFX + placement: + mode: SnapgridCenter + components: + - type: TimedDespawn + lifetime: 0.83 + - type: Transform + anchored: true + - type: Sprite + snapCardinals: true + layers: + - sprite: _Impstation/Mobs/Replicator/replicator_tileset.rsi + state: replicator-tile-anim + shader: unshaded + drawdepth: Mobs + - type: Tag + tags: + - HideContextMenu + - type: PointLight + color: "#8800a3" + radius: 4 + energy: 3.5 + castShadows: false + - type: LightBehaviour + behaviours: + - !type:FadeBehaviour + interpolate: Linear + minDuration: 0.83 + maxDuration: 0.83 + startValue: 0.1 + endValue: 3.5 + property: Energy + enabled: true + isLooped: true + reverseWhenFinished: true diff --git a/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator_roles.yml b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator_roles.yml new file mode 100644 index 00000000000..2b4d6c52ecd --- /dev/null +++ b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicator_roles.yml @@ -0,0 +1,12 @@ +- type: entity + parent: BaseMindRoleAntag + id: MindRoleReplicator + name: Replicator Role + components: + - type: MindRole + roleType: TeamAntagonist + antagPrototype: GenericTeamAntagonist + exclusiveAntag: true + - type: ReplicatorRole + - type: RoleBriefing + briefing: replicator-role-briefing diff --git a/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicators.yml b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicators.yml new file mode 100644 index 00000000000..6532d429e43 --- /dev/null +++ b/Resources/Prototypes/_Impstation/Entities/Mobs/Player/Silicon/Replicators/replicators.yml @@ -0,0 +1,514 @@ +- type: entity + name: replicator + description: It's just a little guy. What harm could it do? + id: BaseMobReplicator + abstract: true + parent: BaseMob + components: + - type: Puller + needsHands: false + - type: Replicator + - type: NameIdentifier + group: Replicator + - type: SiliconLawBound + - type: SiliconLawProvider + laws: Replicator + - type: GhostTakeoverAvailable + - type: GhostRole + name: ghost-role-information-replicator-name + description: ghost-role-information-replicator-desc + rules: ghost-role-information-replicator-rules + mindRoles: + - MindRoleReplicator + raffle: + settings: default + - type: Sprite + granularLayersRendering: true + drawdepth: Mobs + sprite: _Impstation/Mobs/Replicator/replicator.rsi + layers: + - map: ["enum.DamageStateVisualLayers.Base"] + state: alive + - map: ["enum.ReplicatorVisuals.Combat"] + state: combat_level1 + shader: unshaded + visible: false + - type: UserInterface + interfaces: + enum.SiliconLawsUiKey.Key: + type: SiliconLawBoundUserInterface + - type: Appearance + - type: ActionGrant + actions: + - ActionViewLaws + - type: TypingIndicator + proto: replicator + - type: Speech + speechVerb: Robotic + speechSounds: Replicator + - type: Vocal + sounds: + Unsexed: UnisexSilicon + - type: Emoting + - type: DamagedSiliconAccent + - type: ReplacementAccent + accent: silicon + - type: IntrinsicRadioReceiver + - type: IntrinsicRadioTransmitter + channels: + - Binary + - type: ActiveRadio + channels: + - Binary + - type: Actions + - type: ComplexInteraction + - type: ProtectedFromStepTriggers + - type: InputMover + - type: MobMover + - type: ContentEye + maxZoom: 1.2, 1.2 + - type: Tag + tags: + - DoorBumpOpener + - CanPilot + - VimPilot + - SiliconEmotes + - Honker + - type: MobState + allowedStates: + - Alive + - Dead + - type: MobThresholds + thresholds: + 0: Alive + 100: Dead + - type: GuideHelp + guides: + - Cyborgs + - Robotics + - type: Repairable + damage: + types: + Blunt: -10 + Slash: -10 + Piercing: -10 + Structural: -10 + doAfterDelay: 1 + fuelCost: 0.5 + allowSelfRepair: true + - type: Destructible + thresholds: + - trigger: + !type:DamageTypeTrigger + damageType: Blunt + damage: 150 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:SpawnEntitiesBehavior + spawn: + SheetPlasteel1: + min: 1 + max: 5 + - type: Damageable + damageContainer: StructuralInorganic + damageModifierSet: Replicator1 + - type: HealthExaminable + examinableTypes: + - Blunt + - Slash + - Piercing + - Heat + - Shock + - Structural + - type: StatusEffects + allowed: + - Stun + - KnockedDown + - SlowedDown + - Flashed + - TemporaryBlindness + - StaminaModifier + - type: DamageStateVisuals + states: + Alive: + Base: alive + Dead: + Base: dead + - type: ZombieImmune + - type: EmpResistance + strengthMultiplier: 0 + - type: NpcFactionMember + factions: + - Replicator + - type: MeleeWeapon + altDisarm: false + soundHit: + path: /Audio/Weapons/Guns/Gunshots/taser.ogg + angle: 100 + wideAnimationRotation: 0 + animation: WeaponArcSlash + damage: + types: + Slashing: 7 + - type: MovementSpeedModifier + baseWalkSpeed: 2 + baseSprintSpeed: 4 + - type: Stamina + baseCritThreshold: 120 + - type: PassiveDamage + allowedStates: + - Alive + damage: + groups: + Brute: -0.5 + Burn: -0.5 + types: + Shock: -0.5 + Structural: -0.5 + - type: ThermalVision + lightRadius: 7 + color: "#d70aa0" + - type: Prying + pryPowered: true + force: true + speedModifier: 1 + useSound: + path: /Audio/Items/crowbar.ogg + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.25 + density: 100 + mask: + - SmallMobMask + layer: + - SmallMobLayer + +- type: entity + id: MobReplicatorQueen + name: spore + parent: BaseMobReplicator + categories: [ HideSpawnMenu ] + suffix: Queen + components: + - type: Replicator + queen: true + - type: MeleeWeapon + angle: 0 + wideAnimationRotation: 0 + - type: Sprite + granularLayersRendering: true + drawdepth: SmallMobs + sprite: _Impstation/Mobs/Replicator/replicator.rsi + layers: + - map: ["enum.DamageStateVisualLayers.Base"] + state: alive_spore + - map: ["enum.ReplicatorVisuals.Combat"] + state: combat_level1 + shader: unshaded + visible: false + - type: Physics + bodyStatus: InAir + - type: CanMoveInAir + - type: MovementIgnoreGravity + weightless: true + - type: MovementAlwaysTouching + - type: SyncSprite + - type: MovementSpeedModifier + baseWalkSpeed: 2 + baseSprintSpeed: 4.2 + weightlessFriction: 1 + weightlessFrictionNoInput: 2 + weightlessAcceleration: 1.8 + - type: NoSlip + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.2 + density: 100 + mask: + - SmallMobMask + layer: + - SmallMobLayer + - type: NpcFactionMember + factions: + - Replicator + +- type: entity + id: MobReplicator + parent: BaseMobReplicator + categories: [ HideSpawnMenu ] + components: + - type: Hands + showInHands: false + disableExplosionRecursion: true + - type: BorgChassis + maxModules: 1 + hasMindState: robot_e + noMindState: robot_e_r + activateSound: + path: /Audio/_Impstation/Misc/replicator_sfx1.ogg + deactivateSound: + path: /Audio/_Impstation/Misc/replicator_sfx2.ogg + - type: ContainerContainer + containers: + borg_brain: !type:ContainerSlot { } + borg_module: !type:Container { } + - type: Replicator + upgradeActions: + - ActionReplicatorUpgrade2 + - ActionReplicatorUpgrade2Alt + - type: CombatMode + - type: StaminaDamageOnHit + damage: 20 + sound: /Audio/Weapons/egloves.ogg + - type: Physics + bodyStatus: InAir + - type: CanMoveInAir + - type: MovementIgnoreGravity + weightless: true + - type: MovementAlwaysTouching + - type: SyncSprite + - type: MovementSpeedModifier + baseWalkSpeed: 2 + baseSprintSpeed: 4.2 + weightlessFriction: 1 + weightlessFrictionNoInput: 200 + weightlessAcceleration: 1.8 + - type: NoSlip + - type: Sprite + granularLayersRendering: true + drawdepth: SmallMobs + sprite: _Impstation/Mobs/Replicator/replicator.rsi + layers: + - map: ["enum.DamageStateVisualLayers.Base"] + state: alive + - map: ["enum.ReplicatorVisuals.Combat"] + state: combat_level1 + shader: unshaded + visible: false + - type: ContainerFill + containers: + borg_module: + - ReplicatorModuleT1 + - type: NpcFactionMember + factions: + - Replicator + +- type: entity + id: MobReplicatorTier2 + name: deconstructor + parent: BaseMobReplicator + categories: [ HideSpawnMenu ] + suffix: Level 2 + components: + - type: Hands + showInHands: false + disableExplosionRecursion: true + - type: BorgChassis + maxModules: 1 + hasMindState: robot_e + noMindState: robot_e_r + activateSound: + path: /Audio/_Impstation/Misc/replicator_sfx1.ogg + deactivateSound: + path: /Audio/_Impstation/Misc/replicator_sfx2.ogg + - type: ContainerContainer + containers: + borg_brain: !type:ContainerSlot { } + borg_module: !type:Container { } + - type: CombatMode + - type: StaminaDamageOnHit + damage: 20 + sound: /Audio/Weapons/egloves.ogg + - type: Replicator + upgradeStage: 1 + upgradeActions: + - ActionReplicatorUpgrade3 + readyToUpgradeMessage: replicator-upgrade-t2 + - type: MovementSpeedModifier + baseWalkSpeed: 2 + baseSprintSpeed: 4.2 + weightlessFriction: 1 + weightlessFrictionNoInput: 200 + weightlessAcceleration: 1.2 + - type: MovementAlwaysTouching + - type: Sprite + granularLayersRendering: true + drawdepth: Mobs + sprite: _Impstation/Mobs/Replicator/replicator.rsi + layers: + - map: ["enum.DamageStateVisualLayers.Base"] + state: alive_level2 + - map: ["enum.ReplicatorVisuals.Combat"] + state: combat_level2 + shader: unshaded + visible: false + - type: NoSlip + - type: DamageStateVisuals + states: + Alive: + Base: alive_level2 + Dead: + Base: dead_level2 + - type: Damageable + damageContainer: StructuralInorganic + damageModifierSet: Replicator2 + - type: ContainerFill + containers: + borg_module: + - ReplicatorModuleT2Dec + - type: NpcFactionMember + factions: + - Replicator + +- type: entity + id: MobReplicatorTier2Alt + name: defender + parent: BaseMobReplicator + categories: [ HideSpawnMenu ] + suffix: Level 2 Alt + components: + - type: Hands + showInHands: false + disableExplosionRecursion: true + - type: BorgChassis + maxModules: 1 + hasMindState: robot_e + noMindState: robot_e_r + activateSound: + path: /Audio/_Impstation/Misc/replicator_sfx1.ogg + deactivateSound: + path: /Audio/_Impstation/Misc/replicator_sfx2.ogg + - type: ContainerContainer + containers: + borg_brain: !type:ContainerSlot { } + borg_module: !type:Container { } + - type: CombatMode + - type: Replicator + upgradeStage: 1 + upgradeActions: + - ActionReplicatorUpgrade3 + readyToUpgradeMessage: replicator-upgrade-t2 + - type: MovementSpeedModifier + baseWalkSpeed: 2 + baseSprintSpeed: 4.2 + weightlessFriction: 1 + weightlessFrictionNoInput: 2 + weightlessAcceleration: 1.2 + - type: MovementAlwaysTouching + - type: Sprite + granularLayersRendering: true + drawdepth: Mobs + sprite: _Impstation/Mobs/Replicator/replicator.rsi + layers: + - map: ["enum.DamageStateVisualLayers.Base"] + state: alive_level2alt + - map: ["enum.ReplicatorVisuals.Combat"] + state: combat_level2alt + shader: unshaded + visible: false + - type: StaminaDamageOnHit + damage: 20 + sound: /Audio/Weapons/egloves.ogg + - type: NoSlip + - type: DamageStateVisuals + states: + Alive: + Base: alive_level2alt + Dead: + Base: dead_level2 + - type: Damageable + damageContainer: StructuralInorganic + damageModifierSet: Replicator2 + - type: ContainerFill + containers: + borg_module: + - ReplicatorModuleT2Alt + - type: NpcFactionMember + factions: + - Replicator + +- type: entity + id: MobReplicatorTier3 + name: protector + parent: BaseMobReplicator + categories: [ HideSpawnMenu ] + description: Oh boy. + suffix: Level 3 + components: + - type: Hands + showInHands: false + disableExplosionRecursion: true + - type: BorgChassis + maxModules: 1 + hasMindState: robot_e + noMindState: robot_e_r + activateSound: + path: /Audio/_Impstation/Misc/replicator_sfx1.ogg + deactivateSound: + path: /Audio/_Impstation/Misc/replicator_sfx2.ogg + - type: ContainerContainer + containers: + borg_brain: !type:ContainerSlot { } + borg_module: !type:Container { } + - type: CombatMode + - type: Replicator + upgradeStage: 2 + upgradeActions: + - ActionReplicatorUpgrade1 + - type: MovementAlwaysTouching + - type: MovementSpeedModifier + baseWalkSpeed: 2 + baseSprintSpeed: 2.835 + friction: 35 + - type: StaminaDamageOnHit + damage: 20 + sound: /Audio/Weapons/egloves.ogg + - type: Sprite + granularLayersRendering: true + drawdepth: Mobs + sprite: _Impstation/Mobs/Replicator/replicator.rsi + layers: + - map: ["enum.DamageStateVisualLayers.Base"] + state: alive_level3 + - map: ["enum.ReplicatorVisuals.Combat"] + state: combat_level3 + shader: unshaded + visible: false + - type: DamageStateVisuals + states: + Alive: + Base: alive_level3 + Dead: + Base: dead_level3 + - type: ContainerFill + containers: + borg_module: + - ReplicatorModuleT3 + - type: NoSlip + - type: Magboots + - type: Damageable + damageContainer: StructuralInorganic + damageModifierSet: Replicator3 + - type: PassiveDamage + allowedStates: + - Alive + damage: + groups: + Brute: -0.75 + Burn: -0.75 + types: + Shock: -0.5 + Structural: -0.5 + - type: NpcFactionMember + factions: + - Replicator diff --git a/Resources/Prototypes/_Impstation/ai_factions.yml b/Resources/Prototypes/_Impstation/ai_factions.yml new file mode 100644 index 00000000000..cb0eea54068 --- /dev/null +++ b/Resources/Prototypes/_Impstation/ai_factions.yml @@ -0,0 +1,17 @@ +- type: npcFaction + id: Replicator + hostile: + - NanoTrasen + - Dragon + - Mouse + - Passive + - PetsNT + - SimpleHostile + - SimpleNeutral + - Syndicate + - Xeno + - Zombie + - Revolutionary + - Wizard + - Xenoborg + - AllHostile diff --git a/Resources/Textures/_Impstation/Interface/Actions/attributions.yml b/Resources/Textures/_Impstation/Interface/Actions/attributions.yml new file mode 100644 index 00000000000..73f8a8b8fed --- /dev/null +++ b/Resources/Textures/_Impstation/Interface/Actions/attributions.yml @@ -0,0 +1,8 @@ +- files: + - replicator_level1.png + - replicator_level2.png + - replicator_level2alt.png + - replicator_level3.png + license: "Custom" + copyright: "Created by Widgetbeck for Impstation." + source: "https://github.com/impstation/imp-station-14/pull/2490" diff --git a/Resources/Textures/_Impstation/Interface/Actions/replicator_level1.png b/Resources/Textures/_Impstation/Interface/Actions/replicator_level1.png new file mode 100644 index 00000000000..54d32758092 Binary files /dev/null and b/Resources/Textures/_Impstation/Interface/Actions/replicator_level1.png differ diff --git a/Resources/Textures/_Impstation/Interface/Actions/replicator_level2.png b/Resources/Textures/_Impstation/Interface/Actions/replicator_level2.png new file mode 100644 index 00000000000..299cce4197c Binary files /dev/null and b/Resources/Textures/_Impstation/Interface/Actions/replicator_level2.png differ diff --git a/Resources/Textures/_Impstation/Interface/Actions/replicator_level2alt.png b/Resources/Textures/_Impstation/Interface/Actions/replicator_level2alt.png new file mode 100644 index 00000000000..0945f5d7f23 Binary files /dev/null and b/Resources/Textures/_Impstation/Interface/Actions/replicator_level2alt.png differ diff --git a/Resources/Textures/_Impstation/Interface/Actions/replicator_level3.png b/Resources/Textures/_Impstation/Interface/Actions/replicator_level3.png new file mode 100644 index 00000000000..a20d5708498 Binary files /dev/null and b/Resources/Textures/_Impstation/Interface/Actions/replicator_level3.png differ diff --git a/Resources/Textures/_Impstation/Interface/Actions/spawn_nest.png b/Resources/Textures/_Impstation/Interface/Actions/spawn_nest.png new file mode 100644 index 00000000000..b3cc429d269 Binary files /dev/null and b/Resources/Textures/_Impstation/Interface/Actions/spawn_nest.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile.png b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile.png new file mode 100644 index 00000000000..565bcd19278 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_E.png b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_E.png new file mode 100644 index 00000000000..fac8c5744bf Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_E.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_N.png b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_N.png new file mode 100644 index 00000000000..b118d0025ef Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_N.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_S.png b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_S.png new file mode 100644 index 00000000000..878ceb999f0 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_S.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_W.png b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_W.png new file mode 100644 index 00000000000..209e2780600 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_double_edge_W.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_NE.png b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_NE.png new file mode 100644 index 00000000000..582ce085b3c Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_NE.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_NW.png b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_NW.png new file mode 100644 index 00000000000..d10afca850d Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_NW.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_SE.png b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_SE.png new file mode 100644 index 00000000000..91298808905 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_SE.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_SW.png b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_SW.png new file mode 100644 index 00000000000..b5b0d1a79c7 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/Tile/tile_single_edge_SW.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/attributions.yml b/Resources/Textures/_Impstation/Mobs/Replicator/attributions.yml new file mode 100644 index 00000000000..64f2894b32c --- /dev/null +++ b/Resources/Textures/_Impstation/Mobs/Replicator/attributions.yml @@ -0,0 +1,56 @@ +- files: + - replicator.rsi/alive.png + - replicator.rsi/alive_level2.png + - replicator.rsi/alive_level2alt.png + - replicator.rsi/alive_level3.png + - replicator.rsi/alive_spore.png + - replicator.rsi/combat_level1.png + - replicator.rsi/combat_level2.png + - replicator.rsi/combat_level2alt.png + - replicator.rsi/combat_level3.png + - replicator.rsi/dead.png + - replicator.rsi/dead_level2.png + - replicator.rsi/dead_level3.png + - replicator.rsi/icon.png + - replicator.rsi/replicator0.png + - replicator.rsi/t1weapon.png + - replicator.rsi/t2altmelee.png + - replicator.rsi/t2altweapon.png + - replicator.rsi/t3weapon.png + - replicator_gun.rsi/beam_repli.png + - replicator_gun.rsi/beam_repli2.png + - replicator_gun.rsi/impact_repli.png + - replicator_gun.rsi/impact_repli2.png + - replicator_gun.rsi/muzzle_repli.png + - replicator_gun.rsi/muzzle_repli2.png + - replicator_nest.rsi/nest1.png + - replicator_nest.rsi/nest1unshaded.png + - replicator_nest.rsi/nest2.png + - replicator_nest.rsi/nest2unshaded.png + - replicator_nest.rsi/nest3.png + - replicator_nest.rsi/nest3unshaded.png + - replicator_sign.rsi/sign.png + - replicator_tablet.rsi/aac_screen.png + - replicator_tablet.rsi/aac_tablet.png + - replicator_tileset.rsi/replicator-tile-anim.png + - replicator_tileset.rsi/wall.png + - replicator_tileset.rsi/wall0.png + - replicator_tileset.rsi/wall1.png + - replicator_tileset.rsi/wall2.png + - replicator_tileset.rsi/wall3.png + - replicator_tileset.rsi/wall4.png + - replicator_tileset.rsi/wall5.png + - replicator_tileset.rsi/wall6.png + - replicator_tileset.rsi/wall7.png + - Tile/tile.png + - Tile/tile_double_edge_E.png + - Tile/tile_double_edge_N.png + - Tile/tile_double_edge_S.png + - Tile/tile_double_edge_W.png + - Tile/tile_single_edge_NE.png + - Tile/tile_single_edge_NW.png + - Tile/tile_single_edge_SE.png + - Tile/tile_single_edge_SW.png + license: "Custom" + copyright: "Created by Widgetbeck for Impstation." + source: "https://github.com/impstation/imp-station-14/pull/2490" diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive.png new file mode 100644 index 00000000000..c2781f7c9d9 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive_level2.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive_level2.png new file mode 100644 index 00000000000..8a7e37faa96 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive_level2.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive_level2alt.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive_level2alt.png new file mode 100644 index 00000000000..f33dfcba696 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive_level2alt.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive_level3.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive_level3.png new file mode 100644 index 00000000000..bde0338d5f2 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive_level3.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive_spore.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive_spore.png new file mode 100644 index 00000000000..065e358bb20 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/alive_spore.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/combat_level1.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/combat_level1.png new file mode 100644 index 00000000000..a23b0745978 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/combat_level1.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/combat_level2.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/combat_level2.png new file mode 100644 index 00000000000..ebee2083f56 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/combat_level2.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/combat_level2alt.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/combat_level2alt.png new file mode 100644 index 00000000000..ed53a45bfc0 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/combat_level2alt.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/combat_level3.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/combat_level3.png new file mode 100644 index 00000000000..765836a2f58 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/combat_level3.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/dead.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/dead.png new file mode 100644 index 00000000000..aede1007912 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/dead.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/dead_level2.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/dead_level2.png new file mode 100644 index 00000000000..f3d406428b1 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/dead_level2.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/dead_level3.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/dead_level3.png new file mode 100644 index 00000000000..b6f1b782428 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/dead_level3.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/icon.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/icon.png new file mode 100644 index 00000000000..24eaaa32e78 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/icon.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/meta.json b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/meta.json new file mode 100644 index 00000000000..dedcf0d6693 --- /dev/null +++ b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/meta.json @@ -0,0 +1,270 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "AftrLite (github)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "alive", + "directions": 4, + "delays": [ + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ] + ] + }, + { + "name": "alive_level2", + "directions": 4, + "delays": [ + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ] + ] + }, + { + "name": "alive_level2alt", + "directions": 4, + "delays": [ + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ] + ] + }, + { + "name": "alive_level3", + "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, 0.1, 0.1, 0.1, 0.1 + ] + ] + }, + { + "name": "alive_spore", + "directions": 4, + "delays": [ + [ + 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.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2 + ] + ] + }, + { + "name": "dead" + }, + { + "name": "dead_level2" + }, + { + "name": "dead_level3" + }, + { + "name": "combat_level1", + "directions": 4, + "delays": [ + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ] + ] + }, + { + "name": "combat_level2", + "directions": 4, + "delays": [ + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ] + ] + }, + { + "name": "combat_level2alt", + "directions": 4, + "delays": [ + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ], + [ + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ] + ] + }, + { + "name": "combat_level3", + "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, 0.1, 0.1, 0.1, 0.1 + ] + ] + }, + { + "name": "t1weapon" + }, + { + "name": "t3weapon" + }, + { + "name": "t2altweapon" + }, + { + "name": "t2altmelee" + }, + { + "name": "replicator0", + "directions": 1, + "delays": [ + [ + 0.4, 0.4, 0.4, 0.4 + ] + ] + } + ] +} diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/replicator0.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/replicator0.png new file mode 100644 index 00000000000..6b683be20a1 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/replicator0.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/t1weapon.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/t1weapon.png new file mode 100644 index 00000000000..f5716905067 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/t1weapon.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/t2altmelee.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/t2altmelee.png new file mode 100644 index 00000000000..b625e1fe7aa Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/t2altmelee.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/t2altweapon.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/t2altweapon.png new file mode 100644 index 00000000000..f2673d905f8 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/t2altweapon.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/t3weapon.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/t3weapon.png new file mode 100644 index 00000000000..4eaf1102f33 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator.rsi/t3weapon.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/beam_repli.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/beam_repli.png new file mode 100644 index 00000000000..202c67aac4e Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/beam_repli.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/beam_repli2.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/beam_repli2.png new file mode 100644 index 00000000000..235db39638d Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/beam_repli2.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/impact_repli.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/impact_repli.png new file mode 100644 index 00000000000..1974e21c989 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/impact_repli.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/impact_repli2.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/impact_repli2.png new file mode 100644 index 00000000000..07938630ccd Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/impact_repli2.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/meta.json b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/meta.json new file mode 100644 index 00000000000..94facaf386d --- /dev/null +++ b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/meta.json @@ -0,0 +1,101 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "AftrLite (github)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "muzzle_repli", + "delays": [ + [ + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002 + ] + ] + }, + { + "name": "beam_repli", + "delays": [ + [ + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002 + ] + ] + }, + { + "name": "impact_repli", + "delays": [ + [ + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002 + ] + ] + }, + { + "name": "muzzle_repli2", + "delays": [ + [ + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002 + ] + ] + }, + { + "name": "beam_repli2", + "delays": [ + [ + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002 + ] + ] + }, + { + "name": "impact_repli2", + "delays": [ + [ + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002 + ] + ] + } + ] +} diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/muzzle_repli.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/muzzle_repli.png new file mode 100644 index 00000000000..30e141e3043 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/muzzle_repli.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/muzzle_repli2.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/muzzle_repli2.png new file mode 100644 index 00000000000..ef1633f6a07 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_gun.rsi/muzzle_repli2.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/meta.json b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/meta.json new file mode 100644 index 00000000000..7a5a40c2918 --- /dev/null +++ b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/meta.json @@ -0,0 +1,47 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "AftrLite (github)", + "size": { + "x": 96, + "y": 96 + }, + "states": [ + { + "name": "nest1" + }, + { + "name": "nest2" + }, + { + "name": "nest3" + }, + { + "name": "nest1unshaded", + "directions": 1, + "delays": [ + [ + 3, 0.07, 0.07, 0.07, 0.07, 0.07 + ] + ] + }, + { + "name": "nest2unshaded", + "directions": 1, + "delays": [ + [ + 3, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ] + ] + }, + { + "name": "nest3unshaded", + "directions": 1, + "delays": [ + [ + 3, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 + ] + ] + } + ] +} diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest1.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest1.png new file mode 100644 index 00000000000..350b49d009d Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest1.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest1unshaded.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest1unshaded.png new file mode 100644 index 00000000000..b106d648457 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest1unshaded.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest2.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest2.png new file mode 100644 index 00000000000..27bd5d4c9ca Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest2.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest2unshaded.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest2unshaded.png new file mode 100644 index 00000000000..baf438167f0 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest2unshaded.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest3.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest3.png new file mode 100644 index 00000000000..4dc6f78f290 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest3.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest3unshaded.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest3unshaded.png new file mode 100644 index 00000000000..0c28bd8a52f Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_nest.rsi/nest3unshaded.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_sign.rsi/meta.json b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_sign.rsi/meta.json new file mode 100644 index 00000000000..b74d021240a --- /dev/null +++ b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_sign.rsi/meta.json @@ -0,0 +1,37 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "AftrLite (github)", + "size": { + "x": 48, + "y": 48 + }, + "states": [ + { + "name": "sign", + "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, 0.1, 0.1, 0.1, 0.1 + ] + ] + } + ] +} diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_sign.rsi/sign.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_sign.rsi/sign.png new file mode 100644 index 00000000000..bff921bd2d2 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_sign.rsi/sign.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tablet.rsi/aac_screen.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tablet.rsi/aac_screen.png new file mode 100644 index 00000000000..fa43a21261a Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tablet.rsi/aac_screen.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tablet.rsi/aac_tablet.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tablet.rsi/aac_tablet.png new file mode 100644 index 00000000000..ecdce8fa499 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tablet.rsi/aac_tablet.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tablet.rsi/meta.json b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tablet.rsi/meta.json new file mode 100644 index 00000000000..46adb68db49 --- /dev/null +++ b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tablet.rsi/meta.json @@ -0,0 +1,17 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "AAC tablet from https://github.com/Baystation12/Baystation12/tree/17e84546562b97d775cb26790a08e6d87e7f8077 and edited by portfiend. Base tablet from Baystation12 and heavily modified by Flareguy, edited into icon by KOTOB. Edited for Replicators by Widgetbeck.", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "aac_tablet" + }, + { + "name": "aac_screen" + } + ] +} diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/meta.json b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/meta.json new file mode 100644 index 00000000000..143da2c9235 --- /dev/null +++ b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/meta.json @@ -0,0 +1,57 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Sprites by kipdotnet (github) for Impstation, tile variations made by widgetbeck (github).", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "wall" + }, + { + "name": "wall0", + "directions": 4 + }, + { + "name": "wall1", + "directions": 4 + }, + { + "name": "wall2", + "directions": 4 + }, + { + "name": "wall3", + "directions": 4 + }, + { + "name": "wall4", + "directions": 4 + }, + { + "name": "wall5", + "directions": 4 + }, + { + "name": "wall6", + "directions": 4 + }, + { + "name": "wall7", + "directions": 4 + }, + { + "name": "replicator-tile-anim", + "delays": [ + [ + 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, + 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, + 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, + 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03 + ] + ] + } + ] +} diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/replicator-tile-anim.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/replicator-tile-anim.png new file mode 100644 index 00000000000..8d1ea893dd9 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/replicator-tile-anim.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall.png new file mode 100644 index 00000000000..b1e317c6543 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall0.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall0.png new file mode 100644 index 00000000000..d0f2ff231c2 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall0.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall1.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall1.png new file mode 100644 index 00000000000..704f711bcad Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall1.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall2.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall2.png new file mode 100644 index 00000000000..d0f2ff231c2 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall2.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall3.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall3.png new file mode 100644 index 00000000000..704f711bcad Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall3.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall4.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall4.png new file mode 100644 index 00000000000..769827a9644 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall4.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall5.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall5.png new file mode 100644 index 00000000000..9ba324f5123 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall5.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall6.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall6.png new file mode 100644 index 00000000000..769827a9644 Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall6.png differ diff --git a/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall7.png b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall7.png new file mode 100644 index 00000000000..89f652e58ac Binary files /dev/null and b/Resources/Textures/_Impstation/Mobs/Replicator/replicator_tileset.rsi/wall7.png differ diff --git a/Resources/Textures/_Impstation/Objects/Devices/attributions.yml b/Resources/Textures/_Impstation/Objects/Devices/attributions.yml new file mode 100644 index 00000000000..6e20a4c66b6 --- /dev/null +++ b/Resources/Textures/_Impstation/Objects/Devices/attributions.yml @@ -0,0 +1,6 @@ +- files: + - pinpointer-replicator.png + - pinpointer_replicator.rsi/pinpointer-replicator.png + license: "Custom" + copyright: "Created by Widgetbeck for Impstation." + source: "https://github.com/impstation/imp-station-14/pull/2490" diff --git a/Resources/Textures/_Impstation/Objects/Devices/meta.json b/Resources/Textures/_Impstation/Objects/Devices/meta.json new file mode 100644 index 00000000000..d07d6a81e4b --- /dev/null +++ b/Resources/Textures/_Impstation/Objects/Devices/meta.json @@ -0,0 +1,24 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/59f2a4e10e5ba36033c9734ddebfbbdc6157472d, station, modified by Widgetbeck (github)", + "states": [ + { + "name": "pinpointer-replicator", + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + } + ] +} diff --git a/Resources/Textures/_Impstation/Objects/Devices/pinpointer-replicator.png b/Resources/Textures/_Impstation/Objects/Devices/pinpointer-replicator.png new file mode 100644 index 00000000000..07d37a3961e Binary files /dev/null and b/Resources/Textures/_Impstation/Objects/Devices/pinpointer-replicator.png differ diff --git a/Resources/Textures/_Impstation/Objects/Devices/pinpointer_replicator.rsi/meta.json b/Resources/Textures/_Impstation/Objects/Devices/pinpointer_replicator.rsi/meta.json new file mode 100644 index 00000000000..d07d6a81e4b --- /dev/null +++ b/Resources/Textures/_Impstation/Objects/Devices/pinpointer_replicator.rsi/meta.json @@ -0,0 +1,24 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/59f2a4e10e5ba36033c9734ddebfbbdc6157472d, station, modified by Widgetbeck (github)", + "states": [ + { + "name": "pinpointer-replicator", + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + } + ] +} diff --git a/Resources/Textures/_Impstation/Objects/Devices/pinpointer_replicator.rsi/pinpointer-replicator.png b/Resources/Textures/_Impstation/Objects/Devices/pinpointer_replicator.rsi/pinpointer-replicator.png new file mode 100644 index 00000000000..07d37a3961e Binary files /dev/null and b/Resources/Textures/_Impstation/Objects/Devices/pinpointer_replicator.rsi/pinpointer-replicator.png differ