diff --git a/Content.Server/Imperial/SCP/NothingThere/Components/ImperialControlledNothingThereComponent.cs b/Content.Server/Imperial/SCP/NothingThere/Components/ImperialControlledNothingThereComponent.cs new file mode 100644 index 0000000000..e3e538d80f --- /dev/null +++ b/Content.Server/Imperial/SCP/NothingThere/Components/ImperialControlledNothingThereComponent.cs @@ -0,0 +1,30 @@ +using Robust.Shared.Map; +using Robust.Shared.Audio; +using Content.Shared.Chat.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Content.Shared.Damage; +using Robust.Shared.Prototypes; +using Content.Shared.FixedPoint; +using Content.Shared.Mobs.Systems; +namespace Content.Server.Imperial.SCP.NothingThere.Components; + +[RegisterComponent] +public sealed partial class ImperialControlledNothingThereComponent : Component +{ + [DataField("gibBodyAction")] + public EntProtoId GibBodyAction = "ImperialNothingThereGibBodyAction"; + [ViewVariables] + public EntityUid? GibBodyEntity; + [ViewVariables] + public EntityUid OriginalBody = EntityUid.Invalid; + [ViewVariables] + public SoundSpecifier ExitSound = new SoundPathSpecifier("/Audio/Imperial/SCP/nothingthere_gibbody.ogg"); + [ViewVariables] + public int KillCount = 0; + [ViewVariables] + public SoundSpecifier GibSound = new SoundCollectionSpecifier("gib", AudioParams.Default.WithVariation(0.025f)); + [ViewVariables] + public float GibletLaunchImpulse = 150; + [ViewVariables] + public float GibletLaunchImpulseVariance = 3; +} diff --git a/Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereComponent.cs b/Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereComponent.cs new file mode 100644 index 0000000000..ccc8fc5bb4 --- /dev/null +++ b/Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereComponent.cs @@ -0,0 +1,93 @@ +using Robust.Shared.Map; +using Robust.Shared.Audio; +using Content.Shared.Chat.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Content.Shared.Damage; +using Robust.Shared.Prototypes; +using Content.Shared.FixedPoint; +using Content.Shared.Mobs.Systems; +using Content.Shared.Mobs; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; +using Content.Shared.Damage.Prototypes; +using Content.Shared.Polymorph; +namespace Content.Server.Imperial.SCP.NothingThere.Components; + +[RegisterComponent] +public sealed partial class ImperialNothingThereComponent : Component +{ + public SoundSpecifier ChaseSound = new SoundPathSpecifier("/Audio/Imperial/SCP/nothingthere_idle.ogg"); + + [ViewVariables] + public EntityUid? PlayingStream; + + [ViewVariables] + public bool IsPlaying = false; + [DataField("enterBodyAction")] + public EntProtoId EnterBodyAction = "ImperialNothingThereEnterBodyAction"; + public EntityUid? EnterBodyEntity; + + [DataField] + public TimeSpan EnterBodyWindUp = TimeSpan.FromSeconds(2); + [DataField("threshold", required: true)] + public FixedPoint2 Threshold = new(); + [DataField("killsRequired")] + public int KillsRequired = 5; + + [DataField("killCount")] + public int KillCount = 0; + + [DataField("phase")] + public NothingTherePhase Phase = NothingTherePhase.Original; + public EntProtoId? EggEntityProto = "ImperialSCPNothingThereEgg"; + [DataField("transformEggAction")] + public EntProtoId TransformEggAction = "ImperialNothingThereEggAction"; + [DataField("transformEggEntity")] + public EntityUid? TransformEggEntity; + [DataField("enterSound")] + public SoundSpecifier EnterSound = new SoundPathSpecifier("/Audio/Imperial/SCP/nothingthere_enter.ogg"); + + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + public TimeSpan EggTransformDuration = TimeSpan.FromSeconds(30); + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + public TimeSpan EggTransformEnd = TimeSpan.Zero; + [ViewVariables] + public EntProtoId? TrueEntityProto = "ImperialSCPNothingThereTrue"; + [DataField("hatchSound")] + public SoundSpecifier HatchSound = new SoundPathSpecifier("/Audio/Imperial/SCP/nothingthere_hatch.ogg"); + [ViewVariables] + public bool Empowered = false; + [DataField("empowerAction")] + public EntProtoId EmpowerAction = "ImperialNothingThereHelloAction"; + [DataField("empowerEntity")] + public EntityUid? EmpowerEntity; + [DataField("empowerSound")] + public SoundSpecifier EmpowerSound = new SoundPathSpecifier("/Audio/Imperial/SCP/nothingthere_empower.ogg"); + [DataField(required: true), ViewVariables] + public DamageSpecifier EmpowerDamage = new(); + [ViewVariables] + public ProtoId EggMorph = "NothingThereEggMorph"; + [ViewVariables] + public ProtoId TrueMorph = "NothingThereTrueMorph"; + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + [ViewVariables] + public TimeSpan GoodbyeDelay = TimeSpan.FromSeconds(0.5f); + [ViewVariables] + public EntProtoId GoodbyeProto = "ImperialNothingThereEmpowerHit"; + [ViewVariables] + public EntProtoId HitProto = "ImperialNothingThereHit"; + [DataField] + public bool NeedItems = false; + [ViewVariables] + public bool NeedGoodbye = false; + [DataField("projectileAction")] + public EntProtoId ProjectileAction = "ImperialNothingThereProjectileAction"; + [DataField("projectileEntity")] + public EntityUid? ProjectileEntity; +} + +public enum NothingTherePhase : byte +{ + Original = 0, + Egg = 1, + True = 2 +} diff --git a/Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereGoodbyeComponent.cs b/Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereGoodbyeComponent.cs new file mode 100644 index 0000000000..9f634442fd --- /dev/null +++ b/Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereGoodbyeComponent.cs @@ -0,0 +1,19 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Audio; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; +[RegisterComponent] +public sealed partial class ImperialNothingThereGoodbyeComponent : Component +{ + [ViewVariables] + public bool Used = false; + [ViewVariables] + public EntProtoId HitProto = "ImperialNothingThereHit"; + [DataField("empowerSound")] + public SoundSpecifier EmpowerSound = new SoundPathSpecifier("/Audio/Imperial/SCP/nothingthere_empower.ogg"); + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + public TimeSpan AttackDuration = TimeSpan.FromSeconds(1.5); + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + public TimeSpan AttackEnd = TimeSpan.Zero; + [ViewVariables] + public EntityUid WeaponUser = EntityUid.Invalid; +} diff --git a/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThere.ChaseMusic.cs b/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThere.ChaseMusic.cs new file mode 100644 index 0000000000..d1b574196f --- /dev/null +++ b/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThere.ChaseMusic.cs @@ -0,0 +1,60 @@ +using Content.Server.Imperial.SCP.NothingThere.Components; +using Robust.Shared.Audio; +using Content.Shared.Mobs; + +namespace Content.Server.Imperial.SCP.NothingThere.Systems; + +public sealed partial class ImperialNothingThereSystem +{ + + private void InitializeChaseMusic() + { + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnRemove); + SubscribeLocalEvent(OnMobStateChanged); + } + private void OnRemove(EntityUid uid, ImperialNothingThereComponent comp, ComponentRemove args) + { + StopChaseMusic(uid, comp); + } + + public void StartChaseMusic(EntityUid uid, ImperialNothingThereComponent comp) + { + if (comp.IsPlaying) + return; + if (comp.Phase == NothingTherePhase.True) + return; + comp.PlayingStream = _audio.PlayPvs( + comp.ChaseSound, + uid, + AudioParams.Default.WithLoop(true) + )?.Entity; + + comp.IsPlaying = true; + } + + public void StopChaseMusic(EntityUid uid, ImperialNothingThereComponent comp) + { + if (!comp.IsPlaying) + return; + if (comp.Phase == NothingTherePhase.True) + return; + if (comp.PlayingStream != null) + { + _audio.Stop(comp.PlayingStream.Value); + comp.PlayingStream = null; + } + comp.IsPlaying = false; + } + private void OnMobStateChanged(EntityUid uid, ImperialNothingThereComponent comp, MobStateChangedEvent args) + { + if (_mobStateSystem.IsDead(uid) || _mobStateSystem.IsCritical(uid)) + { + StopChaseMusic(uid, comp); + } + else if (_mobStateSystem.IsAlive(uid)) + { + StartChaseMusic(uid, comp); + } + } +} diff --git a/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.Arsenal.cs b/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.Arsenal.cs new file mode 100644 index 0000000000..be6ac394ba --- /dev/null +++ b/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.Arsenal.cs @@ -0,0 +1,128 @@ + +using Content.Server.Imperial.SCP.NothingThere.Components; +using Content.Shared.Imperial.SCP.NothingThere.Events; +using Content.Shared.Weapons.Melee.Events; +using Content.Shared.Hands.Components; +using Content.Shared.Popups; +using Content.Shared.DoAfter; +using Content.Shared.Mobs.Components; +using Robust.Shared.Timing; +namespace Content.Server.Imperial.SCP.NothingThere.Systems; + +public sealed partial class ImperialNothingThereSystem +{ + #region Initialize + private void InitializeArsenal() + { + SubscribeLocalEvent(OnGoodbyeAction); + SubscribeLocalEvent(OnGoodbyeDoAfter); + SubscribeLocalEvent(OnGoodbyeAttack); + } + #endregion + #region Item provision + private void UpdateItemProvide() + { + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var comp)) + { + if (!comp.NeedItems) + continue; + var hands = EnsureComp(uid); + if (_hands.TryGetEmptyHand((uid, hands), out var emptyHand)) + { + EntityUid? hit; + if (comp.NeedGoodbye) + { + hit = Spawn(comp.GoodbyeProto, Transform(uid).Coordinates); + comp.NeedGoodbye = false; + } + else + { + hit = Spawn(comp.HitProto, Transform(uid).Coordinates); + } + if (!_hands.TryForcePickup(uid, hit ?? EntityUid.Invalid, emptyHand, checkActionBlocker: false, handsComp: hands)) + { + QueueDel(hit); + return; + } + else + comp.NeedItems = false; + } + } + var weaponquery = EntityQueryEnumerator(); + while (weaponquery.MoveNext(out var wpnuid, out var wpncomp)) + { + var curTime = _gameTiming.CurTime; + if (wpncomp.WeaponUser == EntityUid.Invalid || wpncomp.AttackEnd < curTime) + continue; + var user = wpncomp.WeaponUser; + if (!TryComp(user, out var hands)) + continue; + wpncomp.AttackEnd = TimeSpan.Zero; + wpncomp.WeaponUser = EntityUid.Invalid; + var handd = _hands.GetActiveHand((user, hands)); + _hands.DoDrop((user, hands), handd!, false, false); + if (Exists(wpnuid)) + QueueDel(wpnuid); + if (TryComp(user, out var scp)) + { + scp.NeedItems = true; + } + } + } + #endregion + #region Goodbye Handle + private void OnGoodbyeAction(Entity ent, ref ImperialNothingThereGoodbyeEvent args) + { + if (args.Handled) + return; + + var doAfterArgs = new DoAfterArgs(EntityManager, ent, ent.Comp.GoodbyeDelay, new ImperialNothingThereGoodbyeDoAfterEvent(), ent) + { + BreakOnMove = true, + BreakOnDamage = false, + NeedHand = false + }; + if (!TryComp(args.Performer, out var mob)) + return; + if (!TryComp(args.Performer, out var comp)) + return; + if (_doAfterSystem.TryStartDoAfter(doAfterArgs)) + { + args.Handled = true; + _popupSystem.PopupEntity(Loc.GetString("nothing-there-goodbye-windup"), ent, PopupType.MediumCaution); + } + args.Handled = true; + } + private void OnGoodbyeDoAfter(Entity ent, ref ImperialNothingThereGoodbyeDoAfterEvent args) + { + if (args.Cancelled || args.Handled) + return; + + var hands = EnsureComp(args.User); + var handd = _hands.GetActiveHand((args.User, hands)); + var wpn = _hands.GetActiveItem((args.User, hands)); + var user = args.User; + _hands.DoDrop((args.User, hands), handd!, false, false); + QueueDel(wpn); + ent.Comp.NeedGoodbye = true; + ent.Comp.NeedItems = true; + } + + private void OnGoodbyeAttack(EntityUid uid, ImperialNothingThereGoodbyeComponent comp, ref MeleeHitEvent args) + { + if (comp.Used || args.Handled) + return; + if (!TryComp(args.User, out var hands)) + return; + args.Handled = true; + _audio.PlayPvs(comp.EmpowerSound, args.User); + comp.Used = true; + var user = args.User; + var handd = _hands.GetActiveHand((user, hands)); + comp.WeaponUser = user; + var curTime = _gameTiming.CurTime; + comp.AttackEnd = curTime + comp.AttackDuration; + } + #endregion +} diff --git a/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.BodyControl.cs b/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.BodyControl.cs new file mode 100644 index 0000000000..36527381b5 --- /dev/null +++ b/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.BodyControl.cs @@ -0,0 +1,205 @@ +using Content.Server.Imperial.SCP.NothingThere.Components; +using Content.Shared.Imperial.SCP.NothingThere.Events; +using Content.Shared.Mobs; +using Content.Shared.Atmos.Rotting; +using Content.Shared.Popups; +using Content.Shared.DoAfter; +using Content.Shared.Mobs.Components; +using Content.Shared.Hands.Components; +using Content.Shared.FixedPoint; +using Content.Shared.Damage.Components; +using Content.Shared.Humanoid; +using Robust.Shared.Audio; +using Content.Shared.Chat; +using Content.Shared.Gibbing; +namespace Content.Server.Imperial.SCP.NothingThere.Systems; + +public sealed partial class ImperialNothingThereSystem +{ + private void InitializeBodyControl() + { + SubscribeLocalEvent(OnControlledMobStateChanged); + SubscribeLocalEvent(OnEnterBodyAction); + SubscribeLocalEvent(OnEnterBodyDoAfter); + SubscribeLocalEvent(OnGibBodyAction); + SubscribeLocalEvent(OnInitControlled); + } + private void OnInitControlled(EntityUid uid, ImperialControlledNothingThereComponent comp, ComponentInit args) + { + if (comp.GibBodyEntity == null) + { + _actions.AddAction(uid, + ref comp.GibBodyEntity, + comp.GibBodyAction); + } + } + private void OnEnterBodyAction(Entity ent, ref ImperialNothingThereEnterBodyEvent args) + { + if (args.Handled) + return; + + args.Handled = true; + var target = args.Target; + + if (target == ent.Owner) + return; // no dude + if (!TryComp(target, out var mobstate)) + { + _popupSystem.PopupEntity( + Loc.GetString("nothingthere-hammaggotson-notalive"), + args.Performer, + args.Performer, + PopupType.MediumCaution); + return; + } + if (mobstate.CurrentState != MobState.Dead) + { + _popupSystem.PopupEntity( + Loc.GetString("nothingthere-hammaggotson-notdead"), + args.Performer, + args.Performer, + PopupType.MediumCaution); + return; + } + if (HasComp(target)) + { + _popupSystem.PopupEntity( + Loc.GetString("nothingthere-hammaggotson-rotting"), + args.Performer, + args.Performer, + PopupType.MediumCaution); + return; + } + if (!HasComp(target)) + { + _popupSystem.PopupEntity( + Loc.GetString("nothingthere-hammaggotson-nonhuman"), + args.Performer, + args.Performer, + PopupType.MediumCaution); + return; + } + + _doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, ent, ent.Comp.EnterBodyWindUp, new ImperialNothingThereEnterBodyDoAfterEvent(), ent, target: target, used: ent) + { + BreakOnMove = true, + BlockDuplicate = true, + DuplicateCondition = DuplicateConditions.None, + }); + var othersMessage = Loc.GetString("nothingthere-hammaggotson-windup-others"); + _popupSystem.PopupEntity( + othersMessage, + args.Performer, + args.Performer, + PopupType.MediumCaution); + } + + private void OnEnterBodyDoAfter(Entity entity, ref ImperialNothingThereEnterBodyDoAfterEvent args) + { + var target = args.Target ?? EntityUid.Invalid; + if (!_mind.TryGetMind(args.User, out var mindId, out var mind)) + return; + if (args.Cancelled || args.Handled || entity.Comp.Deleted) + return; + if (!TryComp(args.User, out var comp)) + return; + if (!TryComp(target, out var thrd)) + return; + if (!TryComp(target, out var mob)) + return; + var control = EnsureComp(target); + if (TryComp(target, out var hands)) + { + foreach (var hand in hands.Hands.Keys) + { + _hands.TryDrop((target, hands), hand!); + } + RemComp(target); + } + if (!_mobThresholdSystem.TryGetDeadThreshold(target, out var ddde)) + return; + RemComp(target); + var nddde = ddde + comp.Threshold ?? FixedPoint2.New(400.0f); + _mobThresholdSystem.SetMobStateThreshold(target, nddde, MobState.Dead, thrd); + _mobThresholdSystem.SetMobStateThreshold(target, FixedPoint2.MaxValue, MobState.Critical, thrd); + _mobStateSystem.ChangeMobState(target, MobState.Alive, mob, args.User); + _mind.TransferTo(mindId, target); + control.KillCount = comp.KillCount; + control.KillCount++; + if (_playerManager.TryGetSessionById(mind.UserId, out var sessionscp) && control.KillCount == comp.KillsRequired) + { + var message = Loc.GetString("nothingthere-hammaggotson-haha"); + _chatM.ChatMessageToOne(ChatChannel.Server, message, Loc.GetString("chat-manager-server-wrap-message", ("message", message)), default, false, sessionscp.Channel); + } + _audio.PlayPvs(comp.EnterSound, target); + var transformA = Transform(args.User); + EnsurePausedMap(); + StopChaseMusic(entity.Owner, entity.Comp); + _transform.SetParent(args.User, transformA, PausedMap!.Value); + control.OriginalBody = args.User; + } + + private void OnControlledMobStateChanged(EntityUid uid, ImperialControlledNothingThereComponent comp, MobStateChangedEvent args) + { + if (!_mind.TryGetMind(uid, out var mindId, out var mind)) + return; + if (_mobStateSystem.IsDead(uid) || _mobStateSystem.IsCritical(uid)) + { + var transformB = Transform(uid); + var coords = transformB.Coordinates; + var newb = comp.OriginalBody; + var transformA = Transform(newb); + _transform.SetParent(newb, transformA, transformB.ParentUid); + _transform.SetCoordinates(newb, transformA, transformB.Coordinates, transformB.LocalRotation); + _mind.TransferTo(mindId, newb); + _audio.PlayPvs(comp.ExitSound, newb); + Gib(uid, comp.GibSound, comp.GibletLaunchImpulse, comp.GibletLaunchImpulseVariance, true); + if (TryComp(newb, out var nt)) + { + nt.KillCount = comp.KillCount; + StartChaseMusic(newb, nt); + } + } + } + public HashSet Gib(EntityUid ent, SoundSpecifier gibSound, float gibletLaunchImpulse, float gibletLaunchImpulseVariance, bool dropGiblets = true, EntityUid? user = null) + { + if (!_destructible.DestroyEntity(ent)) + return new(); + + _audio.PlayPvs(gibSound, ent); + + var gibbed = new HashSet(); + var beingGibbed = new BeingGibbedEvent(gibbed); + RaiseLocalEvent(ent, ref beingGibbed); + + if (dropGiblets) + { + foreach (var giblet in gibbed) + { + _transform.DropNextTo(giblet, ent); + FlingDroppedEntity(giblet, gibletLaunchImpulse, gibletLaunchImpulseVariance); + } + } + + var beforeDeletion = new GibbedBeforeDeletionEvent(gibbed); + RaiseLocalEvent(ent, ref beforeDeletion); + + return gibbed; + } + + private void FlingDroppedEntity(EntityUid target, float gibletLaunchImpulse, float gibletLaunchImpulseVariance) + { + var impulse = gibletLaunchImpulse + _random.NextFloat(gibletLaunchImpulseVariance); + var scatterVec = _random.NextAngle().ToVec() * impulse; + _physics.ApplyLinearImpulse(target, scatterVec); + } + private void OnGibBodyAction(Entity ent, ref ImperialNothingThereGibBodyEvent args) + { + if (args.Handled) + return; + if (!TryComp(args.Performer, out var mob)) + return; + args.Handled = true; + _mobStateSystem.ChangeMobState(args.Performer, MobState.Dead, mob, args.Performer); + } +} diff --git a/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.Egg.cs b/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.Egg.cs new file mode 100644 index 0000000000..696c23a529 --- /dev/null +++ b/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.Egg.cs @@ -0,0 +1,57 @@ +using Content.Shared.Imperial.SCP.NothingThere.Events; +using Content.Shared.Popups; +using Content.Shared.Mobs.Components; +using Content.Server.Imperial.SCP.NothingThere.Components; + +namespace Content.Server.Imperial.SCP.NothingThere.Systems; + +public sealed partial class ImperialNothingThereSystem +{ + + private void InitializeEgg() + { + SubscribeLocalEvent(OnEggAction); + } + + private void OnEggAction(Entity ent, ref ImperialNothingThereEggEvent args) + { + if (args.Handled) + return; + if (!TryComp(args.Performer, out var mob)) + return; + if (!TryComp(args.Performer, out var comp)) + return; + if (!_mind.TryGetMind(args.Performer, out var mindId, out var mind)) + return; + args.Handled = true; + if (comp.KillCount < comp.KillsRequired) + { + _popupSystem.PopupEntity( + Loc.GetString("nothingthere-hammaggotson-morekills"), + args.Performer, + args.Performer, + PopupType.MediumCaution); + return; + } + else + { + _polymorph.PolymorphEntity(args.Performer, comp.EggMorph); + } + } + + private void UpdateEgg() + { + var curTime = _gameTiming.CurTime; + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var entity, out var egg)) + { + if (curTime >= egg.EggTransformEnd && egg.Phase == NothingTherePhase.Egg) + { + if (!_mind.TryGetMind(entity, out var mindId, out var mind)) + continue; + var newb = _polymorph.PolymorphEntity(entity, egg.TrueMorph) ?? EntityUid.Invalid; + _audio.PlayPvs(egg.HatchSound, newb); + } + } + } +} diff --git a/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.PausedMap.cs b/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.PausedMap.cs new file mode 100644 index 0000000000..e82705c292 --- /dev/null +++ b/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.PausedMap.cs @@ -0,0 +1,31 @@ +using Content.Shared.GameTicking; + +namespace Content.Server.Imperial.SCP.NothingThere.Systems; + +public sealed partial class ImperialNothingThereSystem +{ + public EntityUid? PausedMap { get; private set; } + + private void InitializeMap() + { + SubscribeLocalEvent(OnRoundRestart); + } + + private void OnRoundRestart(RoundRestartCleanupEvent _) + { + if (PausedMap == null || !Exists(PausedMap)) + return; + + Del(PausedMap.Value); + } + private void EnsurePausedMap() + { + if (PausedMap != null && Exists(PausedMap)) + return; + + var mapUid = _map.CreateMap(); + _metaData.SetEntityName(mapUid, Loc.GetString("polymorph-paused-map-name")); + _map.SetPaused(mapUid, true); + PausedMap = mapUid; + } +} diff --git a/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.cs b/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.cs new file mode 100644 index 0000000000..215f7080d8 --- /dev/null +++ b/Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.cs @@ -0,0 +1,98 @@ +using Content.Shared.Actions; +using Robust.Shared.Audio.Systems; +using Content.Shared.Mobs.Systems; +using Content.Shared.Popups; +using Content.Shared.DoAfter; +using Content.Shared.Hands.Components; +using Content.Shared.Hands.EntitySystems; +using Robust.Server.GameObjects; +using Content.Server.Mind; +using Content.Server.Imperial.SCP.NothingThere.Components; +using Robust.Shared.Timing; +using Content.Server.Polymorph.Systems; +using Content.Shared.Destructible; +using Robust.Shared.Physics.Systems; +using Robust.Shared.Random; +using Robust.Server.Player; +using Content.Server.Chat.Managers; +using System.Linq.Expressions; +namespace Content.Server.Imperial.SCP.NothingThere.Systems; + +public sealed partial class ImperialNothingThereSystem : EntitySystem +{ + [Dependency] private readonly MetaDataSystem _metaData = default!; + [Dependency] private readonly SharedMapSystem _map = default!; + [Dependency] private readonly SharedActionsSystem _actions = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly MobStateSystem _mobStateSystem = default!; + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; + [Dependency] private readonly SharedHandsSystem _hands = default!; + [Dependency] private readonly TransformSystem _transform = default!; + [Dependency] private readonly MindSystem _mind = default!; + [Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!; + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly PolymorphSystem _polymorph = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SharedDestructibleSystem _destructible = default!; + [Dependency] private readonly SharedPhysicsSystem _physics = default!; + [Dependency] private readonly IChatManager _chatM = default!; + [Dependency] private readonly IPlayerManager _playerManager = default!; + public override void Initialize() + { + base.Initialize(); + InitializeMap(); + InitializeArsenal(); + InitializeBodyControl(); + InitializeChaseMusic(); + InitializeEgg(); + } + public override void Update(float frameTime) + { + base.Update(frameTime); + UpdateItemProvide(); + UpdateEgg(); + } + private void OnInit(EntityUid uid, ImperialNothingThereComponent comp, MapInitEvent args) + { + StartChaseMusic(uid, comp); + switch (comp.Phase) + { + case NothingTherePhase.Original: + if (comp.EnterBodyEntity == null) + { + _actions.AddAction(uid, + ref comp.EnterBodyEntity, + comp.EnterBodyAction); + _actions.AddAction(uid, + ref comp.TransformEggEntity, + comp.TransformEggAction); + } + break; + case NothingTherePhase.Egg: + var curTime = _gameTiming.CurTime; + comp.EggTransformEnd = curTime + comp.EggTransformDuration; + break; + case NothingTherePhase.True: + _actions.AddAction(uid, + ref comp.EmpowerEntity, + comp.EmpowerAction); + _actions.AddAction(uid, + ref comp.ProjectileEntity, + comp.ProjectileAction); + var hands = EnsureComp(uid); + if (_hands.TryGetEmptyHand((uid, hands), out var emptyHand) && comp.NeedItems == true) + { + var hit = Spawn(comp.HitProto, Transform(uid).Coordinates); + if (!_hands.TryForcePickup(uid, hit, emptyHand, checkActionBlocker: false, handsComp: hands)) + { + QueueDel(hit); + return; + } + else + comp.NeedItems = false; + } + break; + } + } +} diff --git a/Content.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereEggEvent.cs b/Content.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereEggEvent.cs new file mode 100644 index 0000000000..617a22ba7c --- /dev/null +++ b/Content.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereEggEvent.cs @@ -0,0 +1,5 @@ +using Content.Shared.Actions; + +namespace Content.Shared.Imperial.SCP.NothingThere.Events; + +public sealed partial class ImperialNothingThereEggEvent : InstantActionEvent { } \ No newline at end of file diff --git a/Content.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereEnterBodyEvent.cs b/Content.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereEnterBodyEvent.cs new file mode 100644 index 0000000000..010f17668d --- /dev/null +++ b/Content.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereEnterBodyEvent.cs @@ -0,0 +1,10 @@ +using Content.Shared.Actions; +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; + +namespace Content.Shared.Imperial.SCP.NothingThere.Events; + +public sealed partial class ImperialNothingThereEnterBodyEvent : EntityTargetActionEvent; + +[Serializable, NetSerializable] +public sealed partial class ImperialNothingThereEnterBodyDoAfterEvent : SimpleDoAfterEvent; \ No newline at end of file diff --git a/Content.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereGibBodyEvent.cs b/Content.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereGibBodyEvent.cs new file mode 100644 index 0000000000..55345928e1 --- /dev/null +++ b/Content.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereGibBodyEvent.cs @@ -0,0 +1,5 @@ +using Content.Shared.Actions; + +namespace Content.Shared.Imperial.SCP.NothingThere.Events; + +public sealed partial class ImperialNothingThereGibBodyEvent : InstantActionEvent { } \ No newline at end of file diff --git a/Content.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereGoodbyeDoAfterEvent.cs b/Content.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereGoodbyeDoAfterEvent.cs new file mode 100644 index 0000000000..2bb54c0285 --- /dev/null +++ b/Content.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereGoodbyeDoAfterEvent.cs @@ -0,0 +1,9 @@ +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; + +namespace Content.Shared.Imperial.SCP.NothingThere.Events; + +[Serializable, NetSerializable] +public sealed partial class ImperialNothingThereGoodbyeDoAfterEvent : SimpleDoAfterEvent +{ +} diff --git a/Resources/Audio/Imperial/SCP/nothingthere_empower.ogg b/Resources/Audio/Imperial/SCP/nothingthere_empower.ogg new file mode 100644 index 0000000000..882385d2da Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_empower.ogg differ diff --git a/Resources/Audio/Imperial/SCP/nothingthere_enter.ogg b/Resources/Audio/Imperial/SCP/nothingthere_enter.ogg new file mode 100644 index 0000000000..c98e62d4a7 Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_enter.ogg differ diff --git a/Resources/Audio/Imperial/SCP/nothingthere_gibbody.ogg b/Resources/Audio/Imperial/SCP/nothingthere_gibbody.ogg new file mode 100644 index 0000000000..c460d97361 Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_gibbody.ogg differ diff --git a/Resources/Audio/Imperial/SCP/nothingthere_goodbyehit.ogg b/Resources/Audio/Imperial/SCP/nothingthere_goodbyehit.ogg new file mode 100644 index 0000000000..d1512717be Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_goodbyehit.ogg differ diff --git a/Resources/Audio/Imperial/SCP/nothingthere_hatch.ogg b/Resources/Audio/Imperial/SCP/nothingthere_hatch.ogg new file mode 100644 index 0000000000..53a70e6da8 Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_hatch.ogg differ diff --git a/Resources/Audio/Imperial/SCP/nothingthere_heartbeat.ogg b/Resources/Audio/Imperial/SCP/nothingthere_heartbeat.ogg new file mode 100644 index 0000000000..d15d02585a Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_heartbeat.ogg differ diff --git a/Resources/Audio/Imperial/SCP/nothingthere_hello.ogg b/Resources/Audio/Imperial/SCP/nothingthere_hello.ogg new file mode 100644 index 0000000000..0f35032b6f Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_hello.ogg differ diff --git a/Resources/Audio/Imperial/SCP/nothingthere_idle.ogg b/Resources/Audio/Imperial/SCP/nothingthere_idle.ogg new file mode 100644 index 0000000000..e78e579339 Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_idle.ogg differ diff --git a/Resources/Audio/Imperial/SCP/nothingthere_idle_true.ogg b/Resources/Audio/Imperial/SCP/nothingthere_idle_true.ogg new file mode 100644 index 0000000000..8b8f123cde Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_idle_true.ogg differ diff --git a/Resources/Audio/Imperial/SCP/nothingthere_projectile.ogg b/Resources/Audio/Imperial/SCP/nothingthere_projectile.ogg new file mode 100644 index 0000000000..6ba2a828f2 Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_projectile.ogg differ diff --git a/Resources/Audio/Imperial/SCP/nothingthere_punch1.ogg b/Resources/Audio/Imperial/SCP/nothingthere_punch1.ogg new file mode 100644 index 0000000000..af09556f18 Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_punch1.ogg differ diff --git a/Resources/Audio/Imperial/SCP/nothingthere_punch2.ogg b/Resources/Audio/Imperial/SCP/nothingthere_punch2.ogg new file mode 100644 index 0000000000..2ec1fe3e66 Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_punch2.ogg differ diff --git a/Resources/Audio/Imperial/SCP/nothingthere_run1.ogg b/Resources/Audio/Imperial/SCP/nothingthere_run1.ogg new file mode 100644 index 0000000000..6dfb2a2782 Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_run1.ogg differ diff --git a/Resources/Audio/Imperial/SCP/nothingthere_run2.ogg b/Resources/Audio/Imperial/SCP/nothingthere_run2.ogg new file mode 100644 index 0000000000..640f67cc93 Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_run2.ogg differ diff --git a/Resources/Audio/Imperial/SCP/nothingthere_scream.ogg b/Resources/Audio/Imperial/SCP/nothingthere_scream.ogg new file mode 100644 index 0000000000..594e0b8bfc Binary files /dev/null and b/Resources/Audio/Imperial/SCP/nothingthere_scream.ogg differ diff --git a/Resources/Locale/ru-RU/Imperial/SCP/actions.ftl b/Resources/Locale/ru-RU/Imperial/SCP/actions.ftl index 7ee14413fc..d95d57cc23 100644 --- a/Resources/Locale/ru-RU/Imperial/SCP/actions.ftl +++ b/Resources/Locale/ru-RU/Imperial/SCP/actions.ftl @@ -12,3 +12,13 @@ ent-ActionSCP106DestroyPuddle = Удалить лужу .desc = Мой компас - это интерес живой. ent-ActionSCPChaseMusic = Переключить музыку погони. .desc = Возможно, стать тем, кто не видит ничего, добровольно – это лучший вариант? +ent-ImperialNothingThereEnterBodyAction = Вгрызться в тело + .desc = Влезь в свежий труп человека, чтобы взять его под контроль. +ent-ImperialNothingThereGibBodyAction = Разорви оболочку + .desc = Тело взрывается в щепки и ты вылезаешь в наружу! +ent-ImperialNothingThereEggAction = Начни преображение + .desc = Тебе необходимо изучить изнутри тела 5 людей, чтобы получить возможность принять свой истинный облик. +ent-ImperialNothingThereHelloAction = До свидания. + .desc = Встреча будет недолгой. +ent-ImperialNothingThereProjectileAction = Привет. + .desc = Людям необходимо сближаться. diff --git a/Resources/Locale/ru-RU/Imperial/SCP/dimensionenteraction.ftl b/Resources/Locale/ru-RU/Imperial/SCP/dimensionenteraction.ftl index 74c0ed26d2..4ff732963d 100644 --- a/Resources/Locale/ru-RU/Imperial/SCP/dimensionenteraction.ftl +++ b/Resources/Locale/ru-RU/Imperial/SCP/dimensionenteraction.ftl @@ -1,4 +1,6 @@ scp106-hammaggotson-urdamned = [color=orange][font size=14][bold]Вы попали в карманное измерение.[/font][font size=12] Вам предстоит найти выход, не так ли? Исследуйте это измерение, может где-то здесь вы сможете найти способ выбраться отсюда - демианский череп. Помните, что вы тут можете быть не одни...[/bold][/font][/color] scp106-hammaggotson-wildhunt = [color=orange][font size=14][bold]Внимание![/font][font size = 12] - {$name} попал в ваше измерение! Удачной охоты ^_^ \ No newline at end of file + {$name} попал в ваше измерение! Удачной охоты ^_^ + +nothingthere-hammaggotson-haha = [color=red][font size=14][bold]Вы чувствуете, что вы нашли то, чего искали. Ваше истинное "Я".[/font] diff --git a/Resources/Locale/ru-RU/Imperial/SCP/entities.ftl b/Resources/Locale/ru-RU/Imperial/SCP/entities.ftl index 814b5b2355..6446686aef 100644 --- a/Resources/Locale/ru-RU/Imperial/SCP/entities.ftl +++ b/Resources/Locale/ru-RU/Imperial/SCP/entities.ftl @@ -4,3 +4,16 @@ ent-PortalSCP106 = нечистая лужа небрежности .desc = Оставшееся после умерших ценно для нас, если они были дороги при жизни. ent-ImperialSCP106Ghost = межпространственное перемещение старика .desc = Все ангелы упали ради тебя, видишь их нет? + +ent-ImperialSCPNothingThere = чудо + .desc = Я не думаю, что тебе стоит приближаться к нему. +ent-ImperialSCPNothingThereEgg = многоглазное яйцо + .desc = Либо беги, либо ломай. +ent-ImperialSCPNothingThereTrue = чудо: аннигиляция всего живого + .desc = ПРИВЕТ!!!! ПОДОЙДИ КО МНЕ!!!! +ent-ImperialNothingThereEmpowerHit = до свидания + .desc = Вина лежит на тебе. +ent-ImperialNothingThereHit = менеджер + .desc = Я тебя люблю. +ent-ImperialProjectileBoneShard = осколок кости + .desc = Ауч. diff --git a/Resources/Locale/ru-RU/Imperial/SCP/popup.ftl b/Resources/Locale/ru-RU/Imperial/SCP/popup.ftl index 5bc1701002..85dab977dc 100644 --- a/Resources/Locale/ru-RU/Imperial/SCP/popup.ftl +++ b/Resources/Locale/ru-RU/Imperial/SCP/popup.ftl @@ -8,4 +8,5 @@ nothingthere-hammaggotson-windup-others = Сущность начинает пр nothingthere-hammaggotson-notalive = Вы можете вселяться только в трупы живых существ. nothingthere-hammaggotson-notdead = Вы не можете вселяться в живых существ. nothingthere-hammaggotson-rotting = Вы не можете вселяться в гниющие трупы. -nothingthere-hammaggotson-morekills = Вы неготовы принять свой истинный обличий. +nothingthere-hammaggotson-morekills = Вы не готовы принять свой истинный облик. +nothingthere-hammaggotson-nonhuman = Вы можете вселяться только в людей. diff --git a/Resources/Locale/ru-RU/Imperial/Seriozha/SCP/locale.ftl b/Resources/Locale/ru-RU/Imperial/Seriozha/SCP/locale.ftl index ee61879cf4..c104e5bf69 100644 --- a/Resources/Locale/ru-RU/Imperial/Seriozha/SCP/locale.ftl +++ b/Resources/Locale/ru-RU/Imperial/Seriozha/SCP/locale.ftl @@ -192,3 +192,7 @@ ent-RubberStampComitetNedra = Печать комитета управления .desc = Печать, повышает уровень важности документа ent-ChemistryBottleSaline = бутылочка физраствора .desc = { ent-BaseChemistryEmptyBottle.desc } +ent-CloakNDADelexor = Плащ командования Недр + .desc = Выдается только самым значимым сотрудникам Недр. +ent-CloakNDAWhite = Подозрительный плащ Недр + .desc = Помните, Совет всегда видит и слышит вас. Для удобности и компактности в плаще уже вшиты диктофон и записывающее Ауидо устройство. Выдаётся всем, кому не лень. diff --git a/Resources/Prototypes/Imperial/SCP/Actions/nothingthere.yml b/Resources/Prototypes/Imperial/SCP/Actions/nothingthere.yml new file mode 100644 index 0000000000..3830412bae --- /dev/null +++ b/Resources/Prototypes/Imperial/SCP/Actions/nothingthere.yml @@ -0,0 +1,68 @@ +- type: entity + id: ImperialNothingThereEnterBodyAction + name: Control body + description: cubism + components: + - type: Action + icon: { sprite : Mobs/Species/Human/organs.rsi, state: "brain" } + iconOn: { sprite : Mobs/Species/Human/organs.rsi, state: "brain" } + priority: 1 + - type: TargetAction + - type: EntityTargetAction + event: !type:ImperialNothingThereEnterBodyEvent + +- type: entity + parent: BaseAction + id: ImperialNothingThereGibBodyAction + name: Gib body + description: ezz + components: + - type: Action + icon: { sprite : Mobs/Species/Human/organs.rsi, state: "eyeball-r" } + state: icon + useDelay: 1 + - type: InstantAction + event: !type:ImperialNothingThereGibBodyEvent + +- type: entity + parent: BaseAction + id: ImperialNothingThereEggAction + name: Transform + description: LIAR DANCER + components: + - type: Action + icon: { sprite : Imperial/SCP/nothingthereegg.rsi, state: "icon" } + state: icon + useDelay: 1 + - type: InstantAction + event: !type:ImperialNothingThereEggEvent + +- type: entity + parent: BaseAction + id: ImperialNothingThereHelloAction + name: Empower attack + description: LIAR DANCER + components: + - type: Action + icon: { sprite : Imperial/SCP/nothingtherewpn2.rsi, state: "icon" } + useDelay: 1 + - type: InstantAction + event: !type:ImperialNothingThereGoodbyeEvent + +- type: entity + id: ImperialNothingThereProjectileAction + name: Throw bone shard + description: yeah. + components: + - type: Action + useDelay: 5 + itemIconStyle: BigAction + sound: !type:SoundPathSpecifier + path: /Audio/Imperial/SCP/nothingthere_hello.ogg + icon: { sprite : Objects/Materials/materials.rsi, state: "bones" } + - type: TargetAction + checkCanAccess: false + range: 60 + - type: WorldTargetAction + event: !type:ProjectileSpellEvent + prototype: ImperialProjectileBoneShard diff --git a/Resources/Prototypes/Imperial/SCP/Entities/nothingthere.yml b/Resources/Prototypes/Imperial/SCP/Entities/nothingthere.yml new file mode 100644 index 0000000000..a637dabed3 --- /dev/null +++ b/Resources/Prototypes/Imperial/SCP/Entities/nothingthere.yml @@ -0,0 +1,245 @@ +- type: entity + name: nothing there + suffix: seriozha, Недра, Ham Maggotson + parent: [ ImperialSCPBase, StripableInventoryBase ] + id: ImperialSCPNothingThere + description: Hello? + components: + - type: Sprite + drawdepth: Mobs + scale: "0.75, 0.75" + layers: + - map: [ "enum.DamageStateVisualLayers.Base" ] + state: jared + sprite: Imperial/SCP/nothingthere1.rsi + - type: MobThresholds + thresholds: + 0: Alive + 2000: Dead + - type: MovementSpeedModifier + baseWalkSpeed: 3.2 + baseSprintSpeed: 2.8 + - type: Puller + - type: Pullable + - type: Tag + tags: + - DoorBumpOpener + - FootstepSound + - type: Access + tags: + - SCPAccesOne + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.4 + density: 300 + mask: + - MobMask + layer: + - MobLayer + - type: ImperialSCPChaseMusic + chaseSound: + path: /Audio/Imperial/Seriozha/SCP/chase/chase1.ogg + params: + volume: -2 + range: 10 + - type: ImperialNothingThere + empowerDamage: + types: + Blunt: 110 + threshold: 200 + - type: MeleeWeapon + hidden: true + altDisarm: false + soundHit: + path: /Audio/Imperial/SCP/nothingthere_punch1.ogg + angle: 0 + animation: WeaponArcClaw + damage: + types: + Blunt: 45 + - type: FootstepModifier + footstepSoundCollection: + collection: FootstepNothingThere + - type: Speech + speechVerb: LargeMob + allowedEmotes: ['Scream'] + - type: Vocal + sounds: + Male: NothingThere + Unsexed: NothingThere + Female: NothingThere + +- type: soundCollection + id: FootstepNothingThere + files: + - /Audio/Imperial/SCP/nothingthere_run1.ogg + +- type: emoteSounds + id: NothingThere + sound: + path: /Audio/Imperial/SCP/nothingthere_scream.ogg + +- type: entity + name: nothing there + suffix: seriozha, Недра, Ham Maggotson + parent: [ ImperialSCPBase, StripableInventoryBase ] + id: ImperialSCPNothingThereEgg + description: Hello? + components: + - type: Sprite + drawdepth: Mobs + scale: "2, 2" + layers: + - map: [ "enum.DamageStateVisualLayers.Base" ] + state: icon + sprite: Imperial/SCP/nothingthereegg.rsi + - type: DamageStateVisuals + states: + Alive: + Base: alive + Dead: + Base: dead + - type: MobThresholds + thresholds: + 0: Alive + 2000: Dead + - type: MovementSpeedModifier + baseWalkSpeed: 0 + baseSprintSpeed: 0 + - type: Puller + - type: Tag + tags: + - DoorBumpOpener + - FootstepSound + - type: Access + tags: + - SCPAccesOne + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.4 + density: 300 + mask: + - MobMask + layer: + - MobLayer + - type: ImperialNothingThere + empowerDamage: + types: + Blunt: 110 + threshold: 200 + chaseSound: /Audio/Imperial/SCP/nothingthere_heartbeat.ogg + phase: 1 + - type: FootstepModifier + footstepSoundCollection: + collection: FootstepNothingThere + - type: Speech + speechVerb: LargeMob + allowedEmotes: ['Scream'] + - type: Vocal + sounds: + Male: NothingThere + Unsexed: NothingThere + Female: NothingThere + - type: MeleeWeapon + hidden: true + range: 0 + altDisarm: false + angle: 0 + damage: + types: + Blunt: 0 + attackRate: 999 + +- type: entity + name: nothing there + suffix: seriozha, Недра, Ham Maggotson + parent: [ ImperialSCPBase ] + id: ImperialSCPNothingThereTrue + description: Hello? + components: + - type: Sprite + drawdepth: Mobs + layers: + - map: [ "enum.DamageStateVisualLayers.Base" ] + state: jared + sprite: Imperial/SCP/nothingthere2.rsi + - type: DamageStateVisuals + states: + Alive: + Base: Hare + BaseUnshaded: glow + Dead: + Base: Hare_die + - type: MobThresholds + thresholds: + 0: Alive + 500: Dead + - type: MovementSpeedModifier + baseWalkSpeed: 3.2 + baseSprintSpeed: 2.8 + - type: Puller + - type: Pullable + - type: Tag + tags: + - DoorBumpOpener + - FootstepSound + - type: Access + tags: + - SCPAccesOne + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.4 + density: 300 + mask: + - MobMask + layer: + - MobLayer + - type: ImperialSCPChaseMusic + chaseSound: + path: /Audio/Imperial/Seriozha/SCP/chase/chase1.ogg + params: + volume: -2 + range: 10 + - type: ImperialNothingThere + needItems: true + empowerDamage: + types: + Blunt: 110 + phase: 2 + threshold: 200 + - type: MeleeWeapon + hidden: true + altDisarm: false + soundHit: + path: /Audio/Imperial/SCP/nothingthere_punch2.ogg + angle: 0 + animation: WeaponArcSmash + damage: + types: + Blunt: 90 + - type: FootstepModifier + footstepSoundCollection: + path: /Audio/Imperial/SCP/nothingthere_run2.ogg + - type: Speech + speechVerb: LargeMob + allowedEmotes: ['Scream'] + - type: Vocal + sounds: + Male: NothingThere + Unsexed: NothingThere + Female: NothingThere + - type: Hands + showInHands: true + activeHandId: Hand + hands: + Hand: + location: Left diff --git a/Resources/Prototypes/Imperial/SCP/Entities/weapon.yml b/Resources/Prototypes/Imperial/SCP/Entities/weapon.yml new file mode 100644 index 0000000000..976d79f21d --- /dev/null +++ b/Resources/Prototypes/Imperial/SCP/Entities/weapon.yml @@ -0,0 +1,41 @@ +- type: entity + name: goodbye + parent: BaseItem + id: ImperialNothingThereEmpowerHit + description: triple baka. + components: + - type: Sprite + sprite: Imperial/SCP/nothingtherewpn2.rsi + state: icon + - type: MeleeWeapon + attackRate: 2 + wideAnimationRotation: -135 + soundHit: + path: /Audio/Imperial/SCP/nothingthere_goodbyehit.ogg + damage: + types: + Slash: 300 + - type: HeldSpeedModifier + sprintModifier: 0 + walkModifier: 0 + - type: Unremoveable + - type: ImperialNothingThereGoodbye + +- type: entity + name: manager + parent: BaseItem + id: ImperialNothingThereHit + description: hatred. + components: + - type: Sprite + sprite: Imperial/SCP/nothingtherewpn1.rsi + state: icon + - type: MeleeWeapon + wideAnimationRotation: -135 + damage: + types: + Blunt: 90 + Structural: 50 + soundHit: + path: /Audio/Imperial/SCP/nothingthere_punch2.ogg + - type: Unremoveable diff --git a/Resources/Prototypes/Imperial/SCP/Misc/nothingtherepolymorph.yml b/Resources/Prototypes/Imperial/SCP/Misc/nothingtherepolymorph.yml new file mode 100644 index 0000000000..3504b96d3e --- /dev/null +++ b/Resources/Prototypes/Imperial/SCP/Misc/nothingtherepolymorph.yml @@ -0,0 +1,29 @@ +- type: polymorph + id: NothingThereEggMorph + configuration: + entity: ImperialSCPNothingThereEgg + forced: true + transferName: false + transferHumanoidAppearance: true + inventory: None + revertOnDeath: false + revertOnCrit: false + polymorphPopup: "" + exitPolymorphPopup: "" + allowRepeatedMorphs: true + transferDamage: false + +- type: polymorph + id: NothingThereTrueMorph + configuration: + entity: ImperialSCPNothingThereTrue + forced: true + transferName: false + transferHumanoidAppearance: true + inventory: None + revertOnDeath: false + revertOnCrit: false + polymorphPopup: "" + exitPolymorphPopup: "" + allowRepeatedMorphs: true + transferDamage: false diff --git a/Resources/Prototypes/Imperial/Seriozha/misc/misc.yml b/Resources/Prototypes/Imperial/Seriozha/misc/misc.yml index 1fe3627648..3d1101f7da 100644 --- a/Resources/Prototypes/Imperial/Seriozha/misc/misc.yml +++ b/Resources/Prototypes/Imperial/Seriozha/misc/misc.yml @@ -41,8 +41,28 @@ parent: ClothingNeckBase id: CloakViolet name: vampire cloak - suffix: Seriozha, Кастомизация + suffix: Seriozha, Кастомизация, Недра description: Worn by high ranking vampires of the transylvanian society of vampires. components: - type: Sprite sprite: Imperial/Seriozha/misc/Customization/violet_cloak.rsi + +- type: entity + parent: ClothingNeckBase + id: CloakNDADelexor + name: vampire cloak + suffix: Seriozha, Кастомизация, Недра + description: Worn by high ranking vampires of the transylvanian society of vampires. + components: + - type: Sprite + sprite: Imperial/Seriozha/misc/Customization/nda_cloak.rsi + +- type: entity + parent: ClothingNeckBase + id: CloakNDAWhite + name: vampire cloak + suffix: Seriozha, Кастомизация, Недра + description: Worn by high ranking vampires of the transylvanian society of vampires. + components: + - type: Sprite + sprite: Imperial/Seriozha/misc/Customization/white_cloak.rsi diff --git a/Resources/Textures/Imperial/SCP/nothingthere1.rsi/jared.png b/Resources/Textures/Imperial/SCP/nothingthere1.rsi/jared.png new file mode 100644 index 0000000000..daa245f334 Binary files /dev/null and b/Resources/Textures/Imperial/SCP/nothingthere1.rsi/jared.png differ diff --git a/Resources/Textures/Imperial/SCP/nothingthere1.rsi/meta.json b/Resources/Textures/Imperial/SCP/nothingthere1.rsi/meta.json new file mode 100644 index 0000000000..f0454fa7db --- /dev/null +++ b/Resources/Textures/Imperial/SCP/nothingthere1.rsi/meta.json @@ -0,0 +1,15 @@ +{ + "version": 1, + "size": { + "x": 64, + "y": 64 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Created by delexor", + "states": [ + { + "name": "jared", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Imperial/SCP/nothingthere2.rsi/jared.png b/Resources/Textures/Imperial/SCP/nothingthere2.rsi/jared.png new file mode 100644 index 0000000000..139e2a77a5 Binary files /dev/null and b/Resources/Textures/Imperial/SCP/nothingthere2.rsi/jared.png differ diff --git a/Resources/Textures/Imperial/SCP/nothingthere2.rsi/meta.json b/Resources/Textures/Imperial/SCP/nothingthere2.rsi/meta.json new file mode 100644 index 0000000000..f0454fa7db --- /dev/null +++ b/Resources/Textures/Imperial/SCP/nothingthere2.rsi/meta.json @@ -0,0 +1,15 @@ +{ + "version": 1, + "size": { + "x": 64, + "y": 64 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Created by delexor", + "states": [ + { + "name": "jared", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Imperial/SCP/nothingthereegg.rsi/icon.png b/Resources/Textures/Imperial/SCP/nothingthereegg.rsi/icon.png new file mode 100644 index 0000000000..c13ae00ae3 Binary files /dev/null and b/Resources/Textures/Imperial/SCP/nothingthereegg.rsi/icon.png differ diff --git a/Resources/Textures/Imperial/SCP/nothingthereegg.rsi/meta.json b/Resources/Textures/Imperial/SCP/nothingthereegg.rsi/meta.json new file mode 100644 index 0000000000..5b95c7ac36 --- /dev/null +++ b/Resources/Textures/Imperial/SCP/nothingthereegg.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "license": "this content is under ICLA licence, read more on https://wiki.imperialspace.net/icla", + "copyright": "PR by crookielv", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + } + ] +} diff --git a/Resources/Textures/Imperial/SCP/nothingtherewpn1.rsi/icon.png b/Resources/Textures/Imperial/SCP/nothingtherewpn1.rsi/icon.png new file mode 100644 index 0000000000..217cd04a14 Binary files /dev/null and b/Resources/Textures/Imperial/SCP/nothingtherewpn1.rsi/icon.png differ diff --git a/Resources/Textures/Imperial/SCP/nothingtherewpn1.rsi/inhand-left.png b/Resources/Textures/Imperial/SCP/nothingtherewpn1.rsi/inhand-left.png new file mode 100644 index 0000000000..d0dac71ecd Binary files /dev/null and b/Resources/Textures/Imperial/SCP/nothingtherewpn1.rsi/inhand-left.png differ diff --git a/Resources/Textures/Imperial/SCP/nothingtherewpn1.rsi/inhand-right.png b/Resources/Textures/Imperial/SCP/nothingtherewpn1.rsi/inhand-right.png new file mode 100644 index 0000000000..d0dac71ecd Binary files /dev/null and b/Resources/Textures/Imperial/SCP/nothingtherewpn1.rsi/inhand-right.png differ diff --git a/Resources/Textures/Imperial/SCP/nothingtherewpn1.rsi/meta.json b/Resources/Textures/Imperial/SCP/nothingtherewpn1.rsi/meta.json new file mode 100644 index 0000000000..fbfaeb0ac2 --- /dev/null +++ b/Resources/Textures/Imperial/SCP/nothingtherewpn1.rsi/meta.json @@ -0,0 +1,22 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "Made by delexor", + "size": { + "x": 64, + "y": 64 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Imperial/SCP/nothingtherewpn2.rsi/icon.png b/Resources/Textures/Imperial/SCP/nothingtherewpn2.rsi/icon.png new file mode 100644 index 0000000000..8c1f9af6f4 Binary files /dev/null and b/Resources/Textures/Imperial/SCP/nothingtherewpn2.rsi/icon.png differ diff --git a/Resources/Textures/Imperial/SCP/nothingtherewpn2.rsi/inhand-left.png b/Resources/Textures/Imperial/SCP/nothingtherewpn2.rsi/inhand-left.png new file mode 100644 index 0000000000..63e9c7b5ef Binary files /dev/null and b/Resources/Textures/Imperial/SCP/nothingtherewpn2.rsi/inhand-left.png differ diff --git a/Resources/Textures/Imperial/SCP/nothingtherewpn2.rsi/inhand-right.png b/Resources/Textures/Imperial/SCP/nothingtherewpn2.rsi/inhand-right.png new file mode 100644 index 0000000000..63e9c7b5ef Binary files /dev/null and b/Resources/Textures/Imperial/SCP/nothingtherewpn2.rsi/inhand-right.png differ diff --git a/Resources/Textures/Imperial/SCP/nothingtherewpn2.rsi/meta.json b/Resources/Textures/Imperial/SCP/nothingtherewpn2.rsi/meta.json new file mode 100644 index 0000000000..fbfaeb0ac2 --- /dev/null +++ b/Resources/Textures/Imperial/SCP/nothingtherewpn2.rsi/meta.json @@ -0,0 +1,22 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "Made by delexor", + "size": { + "x": 64, + "y": 64 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Imperial/Seriozha/misc/Customization/nda_cloak.rsi/equipped-NECK.png b/Resources/Textures/Imperial/Seriozha/misc/Customization/nda_cloak.rsi/equipped-NECK.png new file mode 100644 index 0000000000..5142ae553e Binary files /dev/null and b/Resources/Textures/Imperial/Seriozha/misc/Customization/nda_cloak.rsi/equipped-NECK.png differ diff --git a/Resources/Textures/Imperial/Seriozha/misc/Customization/nda_cloak.rsi/icon.png b/Resources/Textures/Imperial/Seriozha/misc/Customization/nda_cloak.rsi/icon.png new file mode 100644 index 0000000000..3fd70c22d0 Binary files /dev/null and b/Resources/Textures/Imperial/Seriozha/misc/Customization/nda_cloak.rsi/icon.png differ diff --git a/Resources/Textures/Imperial/Seriozha/misc/Customization/nda_cloak.rsi/meta.json b/Resources/Textures/Imperial/Seriozha/misc/Customization/nda_cloak.rsi/meta.json new file mode 100644 index 0000000000..58d942ee53 --- /dev/null +++ b/Resources/Textures/Imperial/Seriozha/misc/Customization/nda_cloak.rsi/meta.json @@ -0,0 +1,275 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Sprited by: @_deklex Discord", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon", + "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 + ]] + }, + { + "name": "equipped-NECK", + "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, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ]], + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/equipped-NECK.png b/Resources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/equipped-NECK.png index db347f7d62..cc64b3e8ac 100644 Binary files a/Resources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/equipped-NECK.png and b/Resources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/equipped-NECK.png differ diff --git a/Resources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/icon.png b/Resources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/icon.png index 283cfcc9ec..a46db38988 100644 Binary files a/Resources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/icon.png and b/Resources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/icon.png differ diff --git a/Resources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/meta.json b/Resources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/meta.json index e2a53329a8..8689bfc147 100644 --- a/Resources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/meta.json +++ b/Resources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/meta.json @@ -8,10 +8,142 @@ }, "states": [ { - "name": "icon" + "name": "icon", + "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 + ]] }, { "name": "equipped-NECK", + "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, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ]], "directions": 4 } ] diff --git a/Resources/Textures/Imperial/Seriozha/misc/Customization/white_cloak.rsi/equipped-NECK.png b/Resources/Textures/Imperial/Seriozha/misc/Customization/white_cloak.rsi/equipped-NECK.png new file mode 100644 index 0000000000..d67b98d7b0 Binary files /dev/null and b/Resources/Textures/Imperial/Seriozha/misc/Customization/white_cloak.rsi/equipped-NECK.png differ diff --git a/Resources/Textures/Imperial/Seriozha/misc/Customization/white_cloak.rsi/icon.png b/Resources/Textures/Imperial/Seriozha/misc/Customization/white_cloak.rsi/icon.png new file mode 100644 index 0000000000..e666a72169 Binary files /dev/null and b/Resources/Textures/Imperial/Seriozha/misc/Customization/white_cloak.rsi/icon.png differ diff --git a/Resources/Textures/Imperial/Seriozha/misc/Customization/white_cloak.rsi/meta.json b/Resources/Textures/Imperial/Seriozha/misc/Customization/white_cloak.rsi/meta.json new file mode 100644 index 0000000000..b514bf216c --- /dev/null +++ b/Resources/Textures/Imperial/Seriozha/misc/Customization/white_cloak.rsi/meta.json @@ -0,0 +1,265 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Sprited by: fufunuru (Ckey)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon", + "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 + ]] + }, + { + "name": "equipped-NECK", + "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, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ]], + "directions": 4 + } + ] +}