diff --git a/Content.Server/Administration/Managers/BanManager.cs b/Content.Server/Administration/Managers/BanManager.cs index 5815fa419a36..e69b927dccd4 100644 --- a/Content.Server/Administration/Managers/BanManager.cs +++ b/Content.Server/Administration/Managers/BanManager.cs @@ -57,7 +57,7 @@ public sealed partial class BanManager : IBanManager, IPostInjectInit public const string SawmillId = "admin.bans"; public const string JobPrefix = "Job:"; - + private readonly HttpClient _httpClient = new(); private string _serverName = string.Empty; private string _webhookUrl = string.Empty; @@ -79,7 +79,7 @@ public void Initialize() BanNotificationChannel, ProcessBanNotification, OnDatabaseNotificationEarlyFilter); - + _cfg.OnValueChanged(StarlightCCVars.DiscordBanWebhook, OnWebhookChanged, true); _cfg.OnValueChanged(CVars.GameHostName, OnServerNameChanged, true); @@ -309,7 +309,7 @@ public async void CreateRoleBan(NetUserId? target, string? targetUsername, NetUs SendRoleBans(session); } } - + public async void WebhookUpdateRoleBans(NetUserId? target, string? targetUsername, NetUserId? banningAdmin, (IPAddress, int)? addressRange, ImmutableTypedHwid? hwid, IReadOnlyCollection roles, uint? minutes, NoteSeverity severity, string reason, DateTimeOffset timeOfBan) { _systems.TryGetEntitySystem(out GameTicker? ticker); @@ -406,7 +406,7 @@ public void PostInject() { _sawmill = _logManager.GetSawmill(SawmillId); } - + #region Webhook private async void SendWebhook(WebhookPayload payload) { @@ -429,7 +429,7 @@ private async void SendWebhook(WebhookPayload payload) return; } } - + private async Task GenerateJobBanPayload(ServerRoleBanDef banDef, IReadOnlyCollection roles, uint? minutes = null) { var hwid = banDef.HWId?.ToString() ?? "null"; @@ -450,38 +450,44 @@ private async Task GenerateJobBanPayload(ServerRoleBanDef banDef string? adminDiscordId = null; string? targetDiscordId = null; - if (_actor.TryGetServerGrain(out var serverGrain)) + try { - if (banDef.BanningAdmin != null) - adminDiscordId = await serverGrain.GetPlayerDiscordId(banDef.BanningAdmin.Value) - .Then(x => x.ToString()); + if (_actor.TryGetServerGrain(out var serverGrain)) + { + if (banDef.BanningAdmin != null) + adminDiscordId = await serverGrain.GetPlayerDiscordId(banDef.BanningAdmin.Value) + .Then(x => x != 0 ? x.ToString() : null); - if (banDef.UserId != null) - targetDiscordId = await serverGrain.GetPlayerDiscordId(banDef.UserId.Value) - .Then(x => x.ToString()); + if (banDef.UserId != null) + targetDiscordId = await serverGrain.GetPlayerDiscordId(banDef.UserId.Value) + .Then(x => x != 0 ? x.ToString() : null); + } + } + catch (Exception) + { } // nulllink end var adminLink = ""; var targetLink = ""; - var mentions = new List{}; + var mentions = new List { }; if (adminDiscordId != null) { adminLink = $"<@{adminDiscordId}>"; - mentions.Add(new User(){Id = adminDiscordId}); + mentions.Add(new User() { Id = adminDiscordId }); } if (targetDiscordId != null) { targetLink = $"<@{targetDiscordId}>"; - mentions.Add(new User(){Id = targetDiscordId}); + mentions.Add(new User() { Id = targetDiscordId }); } var allowedMentions = new Dictionary { { "parse", new List {"users"}.ToArray() } }; - + if (banDef.ExpirationTime != null && minutes != null) // Time ban return new WebhookPayload { @@ -543,7 +549,7 @@ private async Task GenerateJobBanPayload(ServerRoleBanDef banDef }, }; } - + private async Task GenerateBanPayload(ServerBanDef banDef, uint? minutes = null) { var hwid = banDef.HWId?.ToString() ?? "null"; @@ -561,31 +567,38 @@ private async Task GenerateBanPayload(ServerBanDef banDef, uint? string? adminDiscordId = null; string? targetDiscordId = null; - if (_actor.TryGetServerGrain(out var serverGrain)) + try { - if(banDef.BanningAdmin != null) - adminDiscordId = await serverGrain.GetPlayerDiscordId(banDef.BanningAdmin.Value) - .Then(x=>x.ToString()); + if (_actor.TryGetServerGrain(out var serverGrain)) + { + if (banDef.BanningAdmin != null) + adminDiscordId = await serverGrain.GetPlayerDiscordId(banDef.BanningAdmin.Value) + .Then(x => x != 0 ? x.ToString() : null); - if (banDef.UserId != null) - targetDiscordId = await serverGrain.GetPlayerDiscordId(banDef.UserId.Value) - .Then(x => x.ToString()); + if (banDef.UserId != null) + targetDiscordId = await serverGrain.GetPlayerDiscordId(banDef.UserId.Value) + .Then(x => x != 0 ? x.ToString() : null); + } + } + catch (Exception) + { } + // nulllink end var adminLink = ""; var targetLink = ""; - var mentions = new List{}; + var mentions = new List { }; if (adminDiscordId != null) { adminLink = $"<@{adminDiscordId}>"; - mentions.Add(new User(){Id = adminDiscordId}); + mentions.Add(new User() { Id = adminDiscordId }); } if (targetDiscordId != null) { targetLink = $"<@{targetDiscordId}>"; - mentions.Add(new User(){Id = targetDiscordId}); + mentions.Add(new User() { Id = targetDiscordId }); } var allowedMentions = new Dictionary @@ -654,7 +667,7 @@ private async Task GenerateBanPayload(ServerBanDef banDef, uint? }, }; } - + private void OnWebhookChanged(string url) { _webhookUrl = url; @@ -684,12 +697,12 @@ private void OnWebhookChanged(string url) // Fire and forget _ = SetWebhookData(webhookId, webhookToken); } - + private void OnServerNameChanged(string obj) { _serverName = obj; } - + private async Task SetWebhookData(string id, string token) { var response = await _httpClient.GetAsync($"https://discord.com/api/v10/webhooks/{id}/{token}"); @@ -725,7 +738,7 @@ public Embed() { } } - + // https://discord.com/developers/docs/resources/channel#embed-object-embed-author-structure private struct EmbedAuthor { @@ -739,7 +752,7 @@ public EmbedAuthor() { } } - + // https://discord.com/developers/docs/resources/webhook#webhook-object-webhook-structure private struct WebhookData { @@ -753,7 +766,7 @@ public WebhookData() { } } - + // https://discord.com/developers/docs/resources/channel#message-object-message-structure private struct WebhookPayload { diff --git a/Content.Server/Connection/ConnectionManager.Whitelist.cs b/Content.Server/Connection/ConnectionManager.Whitelist.cs index fef95631f436..cf676a8d1fea 100644 --- a/Content.Server/Connection/ConnectionManager.Whitelist.cs +++ b/Content.Server/Connection/ConnectionManager.Whitelist.cs @@ -166,9 +166,19 @@ private bool CheckConditionPlaytime(ConditionPlaytime conditionPlaytime, List CheckNullLinkRolesCondition(NullLinkRolesCondition condition, NetUserId userId) - => _actors.TryGetServerGrain(out var server) - && await server.HasPlayerAnyRole(userId, [.. condition.Roles]); + private async Task CheckNullLinkRolesCondition(NullLinkRolesCondition condition, NetUserId userId) + { + try + { + return _actors.TryGetServerGrain(out var server) + && await server.HasPlayerAnyRole(userId, [.. condition.Roles]); + } + catch (Exception) + { + } + return false; + } + // NullLink Whitelist end private bool CheckConditionNotesPlaytimeRange( diff --git a/Content.Server/Connection/ConnectionManager.cs b/Content.Server/Connection/ConnectionManager.cs index d0f0e880ae2e..48f3f390c2d5 100644 --- a/Content.Server/Connection/ConnectionManager.cs +++ b/Content.Server/Connection/ConnectionManager.cs @@ -271,10 +271,16 @@ session.Status is SessionStatus.Connected or SessionStatus.InGame var bypassAllowed = _cfg.GetCVar(CCVars.BypassBunkerWhitelist) && await _db.GetWhitelistStatusAsync(userId); // NullLink Bypass start - if (!validAccountAge - && _roleReqPeacefulBypass is not null - && _actors.TryGetServerGrain(out var serverGrain)) - validAccountAge = await serverGrain.HasPlayerAnyRole(userId, _roleReqPeacefulBypass.Roles); + try + { + if (!validAccountAge + && _roleReqPeacefulBypass is not null + && _actors.TryGetServerGrain(out var serverGrain)) + validAccountAge = await serverGrain.HasPlayerAnyRole(userId, _roleReqPeacefulBypass.Roles); + } + catch (Exception) + { + } // NullLink Bypass end // Use the custom reason if it exists & they don't have the minimum account age diff --git a/Content.Server/_Starlight/Railroading/HandlerSystem/RailroadingAnnounceHandlerSystem.cs b/Content.Server/_Starlight/Railroading/HandlerSystem/RailroadingAnnounceHandlerSystem.cs new file mode 100644 index 000000000000..94f513cfa683 --- /dev/null +++ b/Content.Server/_Starlight/Railroading/HandlerSystem/RailroadingAnnounceHandlerSystem.cs @@ -0,0 +1,33 @@ +using Content.Server.Chat.Systems; +using Content.Server.GameTicking; +using Content.Shared._Starlight.Railroading; +using Content.Shared._Starlight.Railroading.Events; +using Content.Shared.Starlight.Economy; +using Robust.Server.Player; +using Robust.Shared.Player; +using Robust.Shared.Random; + +namespace Content.Server._Starlight.Railroading; + +public sealed partial class RailroadingAnnounceHandlerSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly ChatSystem _chatSystem = default!; + [Dependency] private readonly GameTicker _gameTicker = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnChosen); + } + + private void OnChosen(Entity ent, ref RailroadingCardChosenEvent args) + => _chatSystem.DispatchFilteredAnnouncement + ( + Filter.Empty().AddWhere(_gameTicker.UserHasJoinedGame), + Loc.GetString(_random.Pick(ent.Comp.Text)), + playSound: ent.Comp.PlaySound, + announcementSound: ent.Comp.Sound, + colorOverride: ent.Comp.Color + ); +} diff --git a/Content.Server/_Starlight/Railroading/HandlerSystem/RailroadingAssignRoleHandlerSystem.cs b/Content.Server/_Starlight/Railroading/HandlerSystem/RailroadingAssignRoleHandlerSystem.cs new file mode 100644 index 000000000000..f8462e1c8ae8 --- /dev/null +++ b/Content.Server/_Starlight/Railroading/HandlerSystem/RailroadingAssignRoleHandlerSystem.cs @@ -0,0 +1,27 @@ +using Content.Server.Mind; +using Content.Server.Roles; +using Content.Shared._Starlight.Railroading; +using Content.Shared._Starlight.Railroading.Events; +using Content.Shared.Mind.Components; +using Content.Shared.Roles.Components; + +namespace Content.Server._Starlight.Railroading; + +public sealed partial class RailroadingAssignRoleHandlerSystem : EntitySystem +{ + [Dependency] private readonly RoleSystem _roles = default!; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnChosen); + } + + private void OnChosen(Entity ent, ref RailroadingCardChosenEvent args) + { + if(TryComp(args.Subject, out var mindContainer) + && mindContainer.Mind.HasValue) + { + _roles.MindAddRole(mindContainer.Mind.Value, ent.Comp.Role); + } + } +} diff --git a/Content.Server/_Starlight/Railroading/HandlerSystem/RailroadingFaxHandlerSystem.cs b/Content.Server/_Starlight/Railroading/HandlerSystem/RailroadingFaxHandlerSystem.cs new file mode 100644 index 000000000000..9d62c21ce906 --- /dev/null +++ b/Content.Server/_Starlight/Railroading/HandlerSystem/RailroadingFaxHandlerSystem.cs @@ -0,0 +1,54 @@ +using Content.Server.Fax; +using Content.Shared._Starlight.Railroading; +using Content.Shared._Starlight.Railroading.Events; +using Content.Shared.DeviceNetwork; +using Content.Shared.DeviceNetwork.Events; +using Content.Shared.Fax.Components; +using Robust.Shared.Random; + +namespace Content.Server._Starlight.Railroading; + +public sealed partial class RailroadingFaxHandlerSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnChosen); + } + + private void OnChosen(Entity ent, ref RailroadingCardChosenEvent args) + { + var letter = _random.Pick(ent.Comp.Letters); + + var payload = new NetworkPayload + { + [DeviceNetworkConstants.Command] = FaxConstants.FaxPrintCommand, + [FaxConstants.FaxPaperNameData] = Loc.GetString(letter.PaperName, ("subject", args.Subject)), + [FaxConstants.FaxPaperContentData] = Loc.GetString(letter.PaperContent, ("subject",args.Subject)), + [FaxConstants.FaxPaperLabelData] = letter.PaperLabel, + [FaxConstants.FaxPaperStampStateData] = letter.StampState, + [FaxConstants.FaxPaperStampedByData] = letter.StampedBy, + [FaxConstants.FaxPaperPrototypeData] = letter.PaperPrototype, + [FaxConstants.FaxPaperLockedData] = letter.Locked + }; + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var faxEnt, out var faxComp)) + { + if (!ent.Comp.Addresses.Contains(faxComp.FaxName)) + continue; + var @event = new DeviceNetworkPacketEvent + ( + 0, + null, + 0, + "NT", + EntityUid.Invalid, + payload + ); + RaiseLocalEvent(faxEnt, @event); + } + } +} diff --git a/Content.Server/_Starlight/Railroading/RailroadingSystem.cs b/Content.Server/_Starlight/Railroading/RailroadingSystem.cs index d67830ad1c69..a9dad3f9e817 100644 --- a/Content.Server/_Starlight/Railroading/RailroadingSystem.cs +++ b/Content.Server/_Starlight/Railroading/RailroadingSystem.cs @@ -132,6 +132,10 @@ public void OnCardSelected(Entity subject, NetEntity card { subject.Comp.ActiveCard = card; _adminLogger.Add(LogType.Railroading, LogImpact.Medium, $"{ToPrettyString(subject)} selected card {ToPrettyString(cardUid)}."); + + var cardPerformer = EnsureComp(card); + cardPerformer.Performer = subject; + var @event = new RailroadingCardChosenEvent(subject); RaiseLocalEvent(card, ref @event); } diff --git a/Content.Server/_Starlight/Railroading/TaskSystems/RailroadingAvoidHandcuffsTaskSystem.cs b/Content.Server/_Starlight/Railroading/TaskSystems/RailroadingAvoidHandcuffsTaskSystem.cs new file mode 100644 index 000000000000..62bafec21cf9 --- /dev/null +++ b/Content.Server/_Starlight/Railroading/TaskSystems/RailroadingAvoidHandcuffsTaskSystem.cs @@ -0,0 +1,55 @@ +using Content.Server._Starlight.Objectives.Events; +using Content.Shared._Starlight.Railroading; +using Content.Shared._Starlight.Railroading.Events; +using Content.Shared.Cuffs; +using Content.Shared.Mobs; +using Content.Shared.Objectives; + +namespace Content.Server._Starlight.Railroading; + +// todo make TaskSystem +public sealed partial class RailroadingAvoidHandcuffsTaskSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnTaskPicked); + SubscribeLocalEvent(OnTaskCompletionQuery); + SubscribeLocalEvent(OnCollectObjectiveInfo); + SubscribeLocalEvent(OnCompleted); + + SubscribeLocalEvent(OnCuffedChanged); + } + + private void OnCompleted(Entity ent, ref RailroadingCardCompletedEvent args) + => RemComp(args.Subject.Owner); + + private void OnCuffedChanged(Entity ent, ref TargetHandcuffedEvent args) + { + if (!TryComp(ent, out var railroadable) + || railroadable.ActiveCard is null + || !TryComp(railroadable.ActiveCard, out var task)) + return; + + task.IsCompleted = false; + RemComp(ent); + } + + private void OnCollectObjectiveInfo(Entity ent, ref CollectObjectiveInfoEvent args) + => args.Objectives.Add(new ObjectiveInfo + { + Title = Loc.GetString(ent.Comp.Message), + Icon = ent.Comp.Icon, + Progress = ent.Comp.IsCompleted ? 1.0f : 0.0f, + }); + + private void OnTaskCompletionQuery(Entity ent, ref RailroadingCardCompletionQueryEvent args) + { + if (args.IsCompleted == false) return; + + args.IsCompleted = ent.Comp.IsCompleted; + } + + private void OnTaskPicked(Entity ent, ref RailroadingCardChosenEvent args) + => EnsureComp(args.Subject.Owner); +} diff --git a/Content.Server/_Starlight/Railroading/TaskSystems/RailroadingSurviveTaskSystem.cs b/Content.Server/_Starlight/Railroading/TaskSystems/RailroadingSurviveTaskSystem.cs new file mode 100644 index 000000000000..b12c8586d074 --- /dev/null +++ b/Content.Server/_Starlight/Railroading/TaskSystems/RailroadingSurviveTaskSystem.cs @@ -0,0 +1,56 @@ +using Content.Server._Starlight.Objectives.Events; +using Content.Shared._Starlight.Railroading; +using Content.Shared._Starlight.Railroading.Events; +using Content.Shared.Mobs; +using Content.Shared.Objectives; + +namespace Content.Server._Starlight.Railroading; + +public sealed partial class RailroadingSurviveTaskSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnTaskPicked); + SubscribeLocalEvent(OnTaskCompletionQuery); + SubscribeLocalEvent(OnCollectObjectiveInfo); + SubscribeLocalEvent(OnCompleted); + + SubscribeLocalEvent(OnMobStateChanged); + } + + private void OnCompleted(Entity ent, ref RailroadingCardCompletedEvent args) + => RemComp(args.Subject.Owner); + + private void OnMobStateChanged(Entity ent, ref MobStateChangedEvent args) + { + if (!TryComp(ent, out var railroadable) + || railroadable.ActiveCard is null + || !TryComp(railroadable.ActiveCard, out var task)) + return; + + if (args.NewMobState == MobState.Dead) + { + task.IsCompleted = false; + RemComp(ent); + } + } + + private void OnCollectObjectiveInfo(Entity ent, ref CollectObjectiveInfoEvent args) + => args.Objectives.Add(new ObjectiveInfo + { + Title = Loc.GetString(ent.Comp.Message), + Icon = ent.Comp.Icon, + Progress = ent.Comp.IsCompleted ? 1.0f : 0.0f, + }); + + private void OnTaskCompletionQuery(Entity ent, ref RailroadingCardCompletionQueryEvent args) + { + if (args.IsCompleted == false) return; + + args.IsCompleted = ent.Comp.IsCompleted; + } + + private void OnTaskPicked(Entity ent, ref RailroadingCardChosenEvent args) + => EnsureComp(args.Subject.Owner); +} diff --git a/Content.Server/_Starlight/Railroading/TaskSystems/RailroadingTimerTaskSystem.cs b/Content.Server/_Starlight/Railroading/TaskSystems/RailroadingTimerTaskSystem.cs new file mode 100644 index 000000000000..03f922a41c3f --- /dev/null +++ b/Content.Server/_Starlight/Railroading/TaskSystems/RailroadingTimerTaskSystem.cs @@ -0,0 +1,70 @@ +using System.Linq; +using System.Threading.Tasks; +using Content.Server._Starlight.Objectives.Events; +using Content.Server.Administration.Managers; +using Content.Server.Administration.Systems; +using Content.Server.EUI; +using Content.Shared._Starlight.Railroading; +using Content.Shared._Starlight.Railroading.Events; +using Content.Shared.Abilities.Goliath; +using Content.Shared.Administration.Logs; +using Content.Shared.Alert; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Nutrition; +using Content.Shared.Objectives; +using Robust.Server.Player; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; + +namespace Content.Server._Starlight.Railroading; + +public sealed partial class RailroadingTimerTaskSystem : AccUpdateEntitySystem +{ + [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly RailroadingSystem _railroading = default!; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnTaskPicked); + SubscribeLocalEvent(OnTaskCompletionQuery); + SubscribeLocalEvent(OnCollectObjectiveInfo); + } + + protected override void AccUpdate() + { + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var ent, out var comp)) + { + if (comp.IsCompleted) continue; + if (comp.EndTime <= _timing.CurTime + && TryComp(ent, out var performer) + && performer.Performer is Entity railroadable) + { + comp.IsCompleted = true; + _railroading.InvalidateProgress(railroadable); + } + } + } + + + private void OnCollectObjectiveInfo(Entity ent, ref CollectObjectiveInfoEvent args) + => args.Objectives.Add(new ObjectiveInfo + { + Title = Loc.GetString(ent.Comp.Message, ("duration", ent.Comp.Duration.TotalMinutes)), + Icon = ent.Comp.Icon, + Progress = Math.Clamp((float)((_timing.CurTime - ent.Comp.Started).TotalSeconds / (_timing.CurTime - ent.Comp.EndTime).TotalSeconds), 0.0f, 1.0f) + }); + + private void OnTaskCompletionQuery(Entity ent, ref RailroadingCardCompletionQueryEvent args) + { + if (args.IsCompleted == false) return; + + args.IsCompleted = ent.Comp.IsCompleted; + } + private void OnTaskPicked(Entity ent, ref RailroadingCardChosenEvent args) + { + ent.Comp.Started = _timing.CurTime; + ent.Comp.EndTime = ent.Comp.Started + ent.Comp.Duration; + } +} diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs index 01886b4a44d8..113ac9ff8499 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs @@ -392,6 +392,11 @@ private void AttemptShoot(EntityUid user, EntityUid gunUid, GunComponent gun) return; } + //Starlight start + var NonEmptyGunShotEvent = new OnNonEmptyGunShotEvent(user, ev.Ammo); + RaiseLocalEvent(gunUid, ref NonEmptyGunShotEvent); + //starlight end + // Handle burstfire if (gun.SelectedMode == SelectiveFire.Burst) { @@ -710,6 +715,11 @@ public record struct AttemptShootEvent(EntityUid User, string? Message, bool Can [ByRefEvent] public record struct GunShotEvent(EntityUid User, List<(EntityUid? Uid, IShootable Shootable)> Ammo); +//starlight start +[ByRefEvent] +public record struct OnNonEmptyGunShotEvent(EntityUid User, List<(EntityUid? Uid, IShootable Shootable)> Ammo); +//starlight end + /// /// Raised on an entity after firing a gun to see if any components or systems would allow this entity to be pushed /// by the gun they're firing. If true, GunSystem will create an impulse on our entity. diff --git a/Content.Shared/_Starlight/Knockback/SharedKnockbackSystem.cs b/Content.Shared/_Starlight/Knockback/SharedKnockbackSystem.cs index 0d8aefc6df02..da3e778d1531 100644 --- a/Content.Shared/_Starlight/Knockback/SharedKnockbackSystem.cs +++ b/Content.Shared/_Starlight/Knockback/SharedKnockbackSystem.cs @@ -25,7 +25,7 @@ public abstract partial class SharedKnockbackSystem : EntitySystem [Dependency] private readonly SharedStaminaSystem _stamina = default!; public override void Initialize() { - SubscribeLocalEvent(OnGunShot); + SubscribeLocalEvent(OnGunShot); SubscribeLocalEvent(OnExamined); } @@ -46,12 +46,12 @@ private void OnExamined(Entity ent, ref ExaminedEve } } - private void OnGunShot(Entity ent, ref TakeAmmoEvent args) + private void OnGunShot(Entity ent, ref OnNonEmptyGunShotEvent args) { //make sure the ammo is shootable foreach (var ammo in args.Ammo) { - if (TryComp(ammo.Entity, out var hitscanCartridge)) + if (TryComp(ammo.Uid, out var hitscanCartridge)) { //check if its spent if (hitscanCartridge.Spent) @@ -60,7 +60,7 @@ private void OnGunShot(Entity ent, ref TakeAmmoEven } } - if (TryComp(ammo.Entity, out var cartridge)) + if (TryComp(ammo.Uid, out var cartridge)) { //check if its spent if (cartridge.Spent) @@ -70,9 +70,7 @@ private void OnGunShot(Entity ent, ref TakeAmmoEven } } - if (args.User == null) - return; - EntityUid user = args.User.Value; + EntityUid user = args.User; //check for tags if (_tagSystem.HasAnyTag(user, ent.Comp.DoestContain.Keys)) diff --git a/Content.Shared/_Starlight/Language/Systems/SharedLanguageSystem.cs b/Content.Shared/_Starlight/Language/Systems/SharedLanguageSystem.cs index 66a86354a165..9552680d0165 100644 --- a/Content.Shared/_Starlight/Language/Systems/SharedLanguageSystem.cs +++ b/Content.Shared/_Starlight/Language/Systems/SharedLanguageSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.GameTicking; using Robust.Shared.Prototypes; using Content.Shared.Cloning.Events; +using Content.Shared.Zombies; namespace Content.Shared._Starlight.Language.Systems; @@ -36,6 +37,8 @@ public override void Initialize() private void OnClone(Entity ent, ref CloningEvent ev) { + if (HasComp(ent)) + return; //if we were zombified cloning will revert this so we dont clone the zed language if (!ev.Settings.EventComponents.Contains(Factory.GetRegistration(ent.Comp.GetType()).Name)) return; var clone = ev.CloneUid; diff --git a/Content.Shared/_Starlight/Railroading/Components/Handlers/RailroadAnnounceComponent.cs b/Content.Shared/_Starlight/Railroading/Components/Handlers/RailroadAnnounceComponent.cs new file mode 100644 index 000000000000..d1a78c35ad58 --- /dev/null +++ b/Content.Shared/_Starlight/Railroading/Components/Handlers/RailroadAnnounceComponent.cs @@ -0,0 +1,19 @@ +using Robust.Shared.Audio; + +namespace Content.Shared._Starlight.Railroading; + +[RegisterComponent] +public sealed partial class RailroadAnnounceOnChosenComponent : Component +{ + [DataField(required: true)] + public List Text = []; + + [DataField] + public bool PlaySound = true; + + [DataField] + public SoundSpecifier? Sound; + + [DataField] + public Color? Color; +} diff --git a/Content.Shared/_Starlight/Railroading/Components/Handlers/RailroadAssignRoleComponent.cs b/Content.Shared/_Starlight/Railroading/Components/Handlers/RailroadAssignRoleComponent.cs new file mode 100644 index 000000000000..0ee9d0d94347 --- /dev/null +++ b/Content.Shared/_Starlight/Railroading/Components/Handlers/RailroadAssignRoleComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared._Starlight.Railroading; + +[RegisterComponent] +public sealed partial class RailroadAssignRoleComponent : Component +{ + [DataField(required: true)] + public EntProtoId Role; +} \ No newline at end of file diff --git a/Content.Shared/_Starlight/Railroading/Components/Handlers/RailroadFaxOnChosenComponent.cs b/Content.Shared/_Starlight/Railroading/Components/Handlers/RailroadFaxOnChosenComponent.cs new file mode 100644 index 000000000000..ccfc833d8c34 --- /dev/null +++ b/Content.Shared/_Starlight/Railroading/Components/Handlers/RailroadFaxOnChosenComponent.cs @@ -0,0 +1,39 @@ +using Content.Shared.Paper; +using Robust.Shared.Audio; + +namespace Content.Shared._Starlight.Railroading; + +[RegisterComponent] +public sealed partial class RailroadFaxOnChosenComponent : Component +{ + [DataField] + public HashSet Addresses = []; + + [DataField(required: true)] + public List Letters = []; +} + +[DataDefinition] +public sealed partial class RailroadFaxLetter +{ + [DataField("name", required: true)] + public string PaperName; + + [DataField("content", required: true)] + public string PaperContent; + + [DataField] + public string? PaperLabel; + + [DataField] + public string? StampState; + + [DataField] + public List StampedBy = []; + + [DataField] + public string PaperPrototype = ""; + + [DataField] + public bool Locked; +} diff --git a/Content.Shared/_Starlight/Railroading/Components/RailroadCardPerformerComponent.cs b/Content.Shared/_Starlight/Railroading/Components/RailroadCardPerformerComponent.cs new file mode 100644 index 000000000000..0718c90ba406 --- /dev/null +++ b/Content.Shared/_Starlight/Railroading/Components/RailroadCardPerformerComponent.cs @@ -0,0 +1,9 @@ +namespace Content.Shared._Starlight.Railroading; + +[RegisterComponent] +public sealed partial class RailroadCardPerformerComponent : Component +{ + [ViewVariables] + [NonSerialized] + public Entity? Performer; +} \ No newline at end of file diff --git a/Content.Shared/_Starlight/Railroading/Components/Tasks/RailroadAvoidHandcuffsTaskComponent.cs b/Content.Shared/_Starlight/Railroading/Components/Tasks/RailroadAvoidHandcuffsTaskComponent.cs new file mode 100644 index 000000000000..3c654f8fe73a --- /dev/null +++ b/Content.Shared/_Starlight/Railroading/Components/Tasks/RailroadAvoidHandcuffsTaskComponent.cs @@ -0,0 +1,16 @@ +using Robust.Shared.Utility; + +namespace Content.Shared._Starlight.Railroading; + +[RegisterComponent] +public sealed partial class RailroadAvoidHandcuffsTaskComponent : Component +{ + [DataField] + public string Message = "rail-avoid-handcuffs-task"; + + [DataField] + public SpriteSpecifier Icon = new SpriteSpecifier.Rsi(new ResPath("Objects/Misc/handcuffs.rsi"), "handcuff"); + + [DataField] + public bool IsCompleted = true; +} \ No newline at end of file diff --git a/Content.Shared/_Starlight/Railroading/Components/Tasks/RailroadConsumeTaskComponent.cs b/Content.Shared/_Starlight/Railroading/Components/Tasks/RailroadConsumeTaskComponent.cs index 740ce2fd9354..94432c8b8429 100644 --- a/Content.Shared/_Starlight/Railroading/Components/Tasks/RailroadConsumeTaskComponent.cs +++ b/Content.Shared/_Starlight/Railroading/Components/Tasks/RailroadConsumeTaskComponent.cs @@ -24,4 +24,3 @@ public sealed partial class RailroadConsumeTaskComponent : Component [DataField] public bool IsCompleted; } - diff --git a/Content.Shared/_Starlight/Railroading/Components/Tasks/RailroadSurviveTaskComponent.cs b/Content.Shared/_Starlight/Railroading/Components/Tasks/RailroadSurviveTaskComponent.cs new file mode 100644 index 000000000000..3663870b61c5 --- /dev/null +++ b/Content.Shared/_Starlight/Railroading/Components/Tasks/RailroadSurviveTaskComponent.cs @@ -0,0 +1,16 @@ +using Robust.Shared.Utility; + +namespace Content.Shared._Starlight.Railroading; + +[RegisterComponent] +public sealed partial class RailroadSurviveTaskComponent : Component +{ + [DataField] + public string Message = "rail-survive-task"; + + [DataField] + public SpriteSpecifier Icon = new SpriteSpecifier.Rsi(new ResPath("Interface/Alerts/human_dead.rsi"), "dead"); + + [DataField] + public bool IsCompleted = true; +} diff --git a/Content.Shared/_Starlight/Railroading/Components/Tasks/RailroadTimerTaskComponent.cs b/Content.Shared/_Starlight/Railroading/Components/Tasks/RailroadTimerTaskComponent.cs new file mode 100644 index 000000000000..b33095d717cd --- /dev/null +++ b/Content.Shared/_Starlight/Railroading/Components/Tasks/RailroadTimerTaskComponent.cs @@ -0,0 +1,29 @@ +using Content.Shared.Chemistry.Reagent; +using Content.Shared.FixedPoint; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; +using Robust.Shared.Utility; + +namespace Content.Shared._Starlight.Railroading; + +[RegisterComponent, AutoGenerateComponentPause] +public sealed partial class RailroadTimerTaskComponent : Component +{ + [DataField] + public string Message = "rail-timer-task"; + + [DataField] + public TimeSpan Duration = TimeSpan.FromMinutes(1); + + [DataField] + public TimeSpan Started = TimeSpan.Zero; + + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField] + public TimeSpan EndTime = TimeSpan.Zero; + + [DataField] + public bool IsCompleted; + + [DataField] + public SpriteSpecifier Icon = new SpriteSpecifier.Rsi(new ResPath("Objects/Devices/goldwatch.rsi"), "goldwatch"); +} + diff --git a/Content.Shared/_Starlight/Railroading/Components/Watchers/RailroadAvoidHandcuffsWatcherComponent.cs b/Content.Shared/_Starlight/Railroading/Components/Watchers/RailroadAvoidHandcuffsWatcherComponent.cs new file mode 100644 index 000000000000..e1a9bb0014c4 --- /dev/null +++ b/Content.Shared/_Starlight/Railroading/Components/Watchers/RailroadAvoidHandcuffsWatcherComponent.cs @@ -0,0 +1,6 @@ +namespace Content.Shared._Starlight.Railroading; + +[RegisterComponent] +public sealed partial class RailroadAvoidHandcuffsWatcherComponent : Component +{ +} \ No newline at end of file diff --git a/Content.Shared/_Starlight/Railroading/Components/Watchers/RailroadMetabolizeWatcherComponent.cs b/Content.Shared/_Starlight/Railroading/Components/Watchers/RailroadMetabolizeWatcherComponent.cs index 297c93951d6f..a9ea131d5157 100644 --- a/Content.Shared/_Starlight/Railroading/Components/Watchers/RailroadMetabolizeWatcherComponent.cs +++ b/Content.Shared/_Starlight/Railroading/Components/Watchers/RailroadMetabolizeWatcherComponent.cs @@ -1,3 +1,5 @@ +using Robust.Shared.Utility; + namespace Content.Shared._Starlight.Railroading; /// @@ -6,4 +8,4 @@ namespace Content.Shared._Starlight.Railroading; [RegisterComponent, Virtual] public partial class RailroadMetabolizerWatcherComponent : Component { -} \ No newline at end of file +} diff --git a/Content.Shared/_Starlight/Railroading/Components/Watchers/RailroadSurviveWatcherComponent.cs b/Content.Shared/_Starlight/Railroading/Components/Watchers/RailroadSurviveWatcherComponent.cs new file mode 100644 index 000000000000..17971c6baa1b --- /dev/null +++ b/Content.Shared/_Starlight/Railroading/Components/Watchers/RailroadSurviveWatcherComponent.cs @@ -0,0 +1,6 @@ +namespace Content.Shared._Starlight.Railroading; + +[RegisterComponent] +public sealed partial class RailroadSurviveWatcherComponent : Component +{ +} \ No newline at end of file diff --git a/Resources/Audio/_Starlight/Music/Jukebox/attributions.yml b/Resources/Audio/_Starlight/Music/Jukebox/attributions.yml new file mode 100644 index 000000000000..6647e7120d18 --- /dev/null +++ b/Resources/Audio/_Starlight/Music/Jukebox/attributions.yml @@ -0,0 +1,9 @@ +- files: ["cc-interns.ogg"] + license: "CC-BY-SA-3.0" + copyright: "CC-Interns by KarmaKitsuna. Made in Suno." + source: "https://suno.com/song/1902325b-b4ab-4989-9554-f8dd2c99ea09?sh=rTAE5vmLV4o9nHmQ" + +- files: [ "steel-and-uranium.ogg" ] + license: "CC-BY-SA-3.0" + copyright: "Steel-and-Uranium by KarmaKitsuna. Made in Suno." + source: "https://suno.com/song/430e6945-fd14-4836-96d0-37f9e797fb9e" \ No newline at end of file diff --git a/Resources/Audio/_Starlight/Music/Jukebox/cc-interns.ogg b/Resources/Audio/_Starlight/Music/Jukebox/cc-interns.ogg new file mode 100644 index 000000000000..6ac402df577d Binary files /dev/null and b/Resources/Audio/_Starlight/Music/Jukebox/cc-interns.ogg differ diff --git a/Resources/Audio/_Starlight/Music/Jukebox/steel-and-uranium.ogg b/Resources/Audio/_Starlight/Music/Jukebox/steel-and-uranium.ogg new file mode 100644 index 000000000000..398724c1d9e3 Binary files /dev/null and b/Resources/Audio/_Starlight/Music/Jukebox/steel-and-uranium.ogg differ diff --git a/Resources/Changelog/ChangelogStarlight.yml b/Resources/Changelog/ChangelogStarlight.yml index 719e8ed84070..ca92eda012bc 100644 --- a/Resources/Changelog/ChangelogStarlight.yml +++ b/Resources/Changelog/ChangelogStarlight.yml @@ -12359,5 +12359,91 @@ Entries: id: 143700 time: '2025-08-22T22:18:55.000000+00:00' url: https://github.com/ss14Starlight/space-station-14/pull/1437 +- author: Karma and Quantum + changes: + - message: 2 new songs for the jukebox + type: Add + id: 143500 + time: '2025-08-23T15:32:28.000000+00:00' + url: https://github.com/ss14Starlight/space-station-14/pull/1435 +- author: walksanatora + changes: + - message: Cloning a zed no longer only makes them only speak zed. + type: Fix + id: 145300 + time: '2025-08-23T18:34:18.000000+00:00' + url: https://github.com/ss14Starlight/space-station-14/pull/1453 +- author: Fractalflower + changes: + - message: Vulpkanins can now understand Fox and Dog + type: Add + id: 144600 + time: '2025-08-24T16:21:54.000000+00:00' + url: https://github.com/ss14Starlight/space-station-14/pull/1446 +- author: Fractalflower + changes: + - message: Felionoids can now understand Cat + type: Add + id: 144601 + time: '2025-08-24T16:21:54.000000+00:00' + url: https://github.com/ss14Starlight/space-station-14/pull/1446 +- author: Fractalflower + changes: + - message: Corgis and foxes can now understand Canilunzt + type: Add + id: 144602 + time: '2025-08-24T16:21:54.000000+00:00' + url: https://github.com/ss14Starlight/space-station-14/pull/1446 +- author: Fractalflower + changes: + - message: Cats can now understand Nekomimetic + type: Add + id: 144603 + time: '2025-08-24T16:21:54.000000+00:00' + url: https://github.com/ss14Starlight/space-station-14/pull/1446 +- author: Fractalflower + changes: + - message: Mothroaches no longer speak Moffic + type: Remove + id: 144604 + time: '2025-08-24T16:21:54.000000+00:00' + url: https://github.com/ss14Starlight/space-station-14/pull/1446 +- author: Fractalflower + changes: + - message: Mothroaches now speak their own language + type: Add + id: 144605 + time: '2025-08-24T16:21:54.000000+00:00' + url: https://github.com/ss14Starlight/space-station-14/pull/1446 +- author: Fractalflower + changes: + - message: Mothroaches can now understand, but not speak, Moffic + type: Add + id: 144606 + time: '2025-08-24T16:21:54.000000+00:00' + url: https://github.com/ss14Starlight/space-station-14/pull/1446 +- author: Fractalflower + changes: + - message: Mothpeople now understand, but cannot speak, Mothroach + type: Add + id: 144607 + time: '2025-08-24T16:21:54.000000+00:00' + url: https://github.com/ss14Starlight/space-station-14/pull/1446 +- author: Happyrobot33 + changes: + - message: Fixed knockback always occuring even when the gun was empty. + type: Fix + id: 145200 + time: '2025-08-24T18:35:59.000000+00:00' + url: https://github.com/ss14Starlight/space-station-14/pull/1452 +- author: Darkrell + changes: + - message: An antagonist card has been added - Criminal. Fulfilling the requirements within 20 minutes makes you a Syndicate member. + type: Add + - message: The railroading system is fully enabled. + type: Tweak + id: 145199 + time: '2025-08-24T18:35:59.000000+00:00' + url: https://github.com/ss14Starlight/space-station-14/pull/1461 Order: -1 diff --git a/Resources/Locale/en-US/_Starlight/Language/languages.ftl b/Resources/Locale/en-US/_Starlight/Language/languages.ftl index 4bcd91626c08..cc41cae9efab 100644 --- a/Resources/Locale/en-US/_Starlight/Language/languages.ftl +++ b/Resources/Locale/en-US/_Starlight/Language/languages.ftl @@ -40,6 +40,9 @@ language-Ancestor-description = The proto-language primarily utilized by monkeys language-Mouse-name = Mouse language-Mouse-description = Squeeek! +language-Mothroach-name = Mothroach +language-Mothroach-description = chitters! + language-Scratch-name = Scratch language-Scratch-description = A simplified, written dialect of the Avali and Resomi. Scratch is the galactic standard language model for the Illuminate. The origins of this language come from the pre-space age nomadic tribes, whose carvings and etches into ice caves hold a striking similarity to the modern Scratch. diff --git a/Resources/Locale/en-US/_Starlight/rail/fax-based.ftl b/Resources/Locale/en-US/_Starlight/rail/fax-based.ftl new file mode 100644 index 000000000000..e6a600e22d92 --- /dev/null +++ b/Resources/Locale/en-US/_Starlight/rail/fax-based.ftl @@ -0,0 +1,21 @@ +rr-criminal = Сriminal +rr-criminal-desc = That was a mistake, at any moment I could be reported and the hunt would begin. + +rr-criminal-letter-name = ORDER, dangerous criminal {$subject} is wanted. +rr-criminal-1-letter-content = [logo] [cclogo] + +     [head=3]NT Information Security Department[/head] + +   [center][color=#006666][italic][bold] Order for the immediate interception[/bold][/italic][/color][/center] + ───────────────────────────────────────── + A dangerous criminal {$subject} has infiltrated your station. + {SUBJECT($subject)} {CONJUGATE-BE($subject)} charged with multiple counts of ████████████████████ , as well as ██████████████. + There is also clear evidence pointing to crimes of a ██████████████ nature against █████████████. {SUBJECT($subject)} may be armed. + + In accordance with Directive 25, Section B of the Code of Information Crimes, you are ordered to deliver {OBJECT($subject)} to Central Command, dead or alive. + + Failure to comply with this order may result in charges of incompetence and dismissal. + ───────────────────────────────────────── + ⠀ [italic]Place for stamps[/italic] + +rr-nt-isd = NT ISD diff --git a/Resources/Locale/en-US/_Starlight/rail/task.ftl b/Resources/Locale/en-US/_Starlight/rail/task.ftl new file mode 100644 index 000000000000..29fbc579053f --- /dev/null +++ b/Resources/Locale/en-US/_Starlight/rail/task.ftl @@ -0,0 +1,3 @@ +rail-timer-task = Do not fail the mission within {$duration} minutes. +rail-survive-task = Survive until all other tasks are completed. +rail-avoid-handcuffs-task = Avoid being handcuffed or restrained. \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 5f4cb0a672b4..1e824fc16911 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -489,9 +489,10 @@ # Starlight-start: Languages - type: LanguageKnowledge speaks: - - Moffic + - Mothroach understands: - Moffic + - Mothroach # Starlight-end - type: GhostRole makeSentient: true @@ -2776,6 +2777,7 @@ - Fox understands: - Fox + - Canilunzt # Starlight-end - type: Sprite drawdepth: Mobs @@ -2904,6 +2906,7 @@ - Dog understands: - Dog + - Canilunzt # Starlight-end - type: DamageStateVisuals states: @@ -3024,6 +3027,7 @@ - Cat understands: - Cat + - Nekomimetic # Starlight-end - type: Sprite drawdepth: Mobs diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/moproach.yml b/Resources/Prototypes/Entities/Mobs/NPCs/moproach.yml index a3c5aa6ec049..a181f2f0b8da 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/moproach.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/moproach.yml @@ -7,9 +7,10 @@ # Starlight-start: Languages - type: LanguageKnowledge speaks: - - Moffic + - Mothroach understands: - Moffic + - Mothroach - GalacticCommon # Starlight-end - type: GhostRole diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml index 08932feeeaab..d691bc353725 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml @@ -213,6 +213,7 @@ understands: - Cat - GalacticCommon + - Nekomimetic # Starlight-end - type: NpcFactionMember factions: @@ -250,6 +251,7 @@ understands: - Cat - GalacticCommon + - Nekomimetic # Starlight-end - type: NpcFactionMember factions: @@ -340,6 +342,7 @@ understands: - Cat - GalacticCommon + - Nekomimetic # Starlight-end - type: Sprite drawdepth: Mobs diff --git a/Resources/Prototypes/Entities/Mobs/Species/moth.yml b/Resources/Prototypes/Entities/Mobs/Species/moth.yml index f70661a3de63..939905cfef97 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/moth.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/moth.yml @@ -13,6 +13,7 @@ understands: - GalacticCommon - Moffic + - Mothroach # Starlight-end - type: Jump action: JumpMoth diff --git a/Resources/Prototypes/_StarLight/Catalog/Jukebox/Standard.yml b/Resources/Prototypes/_StarLight/Catalog/Jukebox/Standard.yml new file mode 100644 index 000000000000..11921ede24bc --- /dev/null +++ b/Resources/Prototypes/_StarLight/Catalog/Jukebox/Standard.yml @@ -0,0 +1,11 @@ +- type: jukebox + id: SteelandUranium + name: Karma + Quantum - Steel and Uranium + path: + path: /Audio/_Starlight/Music/Jukebox/steel-and-uranium.ogg + +- type: jukebox + id: CCInterns + name: Karma - CC Interns + path: + path: /Audio/_Starlight/Music/Jukebox/cc-interns.ogg diff --git a/Resources/Prototypes/_StarLight/Entities/Mobs/Species/felionoid.yml b/Resources/Prototypes/_StarLight/Entities/Mobs/Species/felionoid.yml index 61b35e4b3b4d..f5277449e3ff 100644 --- a/Resources/Prototypes/_StarLight/Entities/Mobs/Species/felionoid.yml +++ b/Resources/Prototypes/_StarLight/Entities/Mobs/Species/felionoid.yml @@ -10,6 +10,7 @@ understands: - GalacticCommon - Nekomimetic + - Cat - type: Absorbable - type: Speech speechVerb: Felionoid @@ -37,7 +38,7 @@ 150: Dead - type: SlowOnDamage speedModifierThresholds: - 45: 0.7 + 45: 0.7 60: 0.5 - type: Butcherable butcheringType: Spike @@ -81,7 +82,7 @@ - AnomalyHost - Felionoid - type: Fixtures - fixtures: + fixtures: fix1: shape: !type:PhysShapeCircle diff --git a/Resources/Prototypes/_StarLight/Entities/Mobs/Species/vulpkanin.yml b/Resources/Prototypes/_StarLight/Entities/Mobs/Species/vulpkanin.yml index f115ec7d88a5..5e518d005df3 100644 --- a/Resources/Prototypes/_StarLight/Entities/Mobs/Species/vulpkanin.yml +++ b/Resources/Prototypes/_StarLight/Entities/Mobs/Species/vulpkanin.yml @@ -12,6 +12,8 @@ understands: - GalacticCommon - Canilunzt + - Fox # "vaguely canidae" + - Dog # "vaguely canidae" - type: Absorbable - type: HumanoidAppearance species: Vulpkanin diff --git a/Resources/Prototypes/_StarLight/Entities/Objects/Deliveries/deliveries.yml b/Resources/Prototypes/_StarLight/Entities/Objects/Deliveries/deliveries.yml index 9bfad0940595..3bd83dfb7f6c 100644 --- a/Resources/Prototypes/_StarLight/Entities/Objects/Deliveries/deliveries.yml +++ b/Resources/Prototypes/_StarLight/Entities/Objects/Deliveries/deliveries.yml @@ -75,4 +75,13 @@ - type: ContainerFill containers: delivery: - - PlushieCarp \ No newline at end of file + - PlushieCarp + +- type: entity + parent: LetterDeliveryEvil + id: PackageDeliveryRewardSyndicateLetter + components: + - type: ContainerFill + containers: + delivery: + - RRMailSyndicateSpamLetter \ No newline at end of file diff --git a/Resources/Prototypes/_StarLight/Entities/Objects/Deliveries/deliveries_items.yml b/Resources/Prototypes/_StarLight/Entities/Objects/Deliveries/deliveries_items.yml index 5313116ec128..dc4a05df92ee 100644 --- a/Resources/Prototypes/_StarLight/Entities/Objects/Deliveries/deliveries_items.yml +++ b/Resources/Prototypes/_StarLight/Entities/Objects/Deliveries/deliveries_items.yml @@ -12,6 +12,20 @@ - antag: Traitor targetComponent: TraitorRule +- type: entity + id: RRMailSyndicateSpamLetter + name: Reasons to choose The Syndicate! + description: An advertisement for the Syndicate. Wont fit in a fax somehow. + parent: [ Paper, BaseSyndicateContraband ] + components: + - type: Paper + content: delivery-spam-reasons-to-join-syndicate + - type: AntagOnSign + chance: 1.00 + antags: + - antag: Traitor + targetComponent: TraitorRule + - type: entity id: MailSpamDontYouWantMore name: Don't You Want More? diff --git a/Resources/Prototypes/_StarLight/GameRules/railroading.yml b/Resources/Prototypes/_StarLight/GameRules/railroading.yml index 6a2e114bd989..ec4a033ff9e4 100644 --- a/Resources/Prototypes/_StarLight/GameRules/railroading.yml +++ b/Resources/Prototypes/_StarLight/GameRules/railroading.yml @@ -18,8 +18,9 @@ # - RRCardFoodMelonFruitBowl # - RRCardFoodStew # - RRCardMetabolizeNicotine - - RRCardMetabolizeTest - +# - RRCardMetabolizeTest + - RRCardCriminal + - type: entity parent: BaseGameRule id: RailroadingMinor @@ -33,6 +34,12 @@ preSpawnDelay: 10 delay: 10 cards: + # antagonists + + - RRCardCriminal + + # Metabolize: Food + - RRCardFoodSashimi - RRCardFoodApplePie - RRCardFoodDumplings diff --git a/Resources/Prototypes/_StarLight/Language/Animals/mothroach.yml b/Resources/Prototypes/_StarLight/Language/Animals/mothroach.yml new file mode 100644 index 000000000000..c2d4f4498846 --- /dev/null +++ b/Resources/Prototypes/_StarLight/Language/Animals/mothroach.yml @@ -0,0 +1,9 @@ +- type: language + id: Mothroach + icon: LanguageIconMoth + obfuscation: + !type:ReplacementObfuscation + replacement: + - Chirp! + - Chitter! + - Squeak! \ No newline at end of file diff --git a/Resources/Prototypes/_StarLight/Railroading/metabolize/base_metabolize.yml b/Resources/Prototypes/_StarLight/Railroading/metabolize/base_metabolize.yml index 8b0382473bc0..07fb00d56bcf 100644 --- a/Resources/Prototypes/_StarLight/Railroading/metabolize/base_metabolize.yml +++ b/Resources/Prototypes/_StarLight/Railroading/metabolize/base_metabolize.yml @@ -38,7 +38,7 @@ - type: RailroadSpawnFlow count: min: 1 - max: 3 + max: 5 - type: RailroadCard title: rr-smoke icon: "" diff --git a/Resources/Prototypes/_StarLight/Railroading/metabolize/fax_based.yml b/Resources/Prototypes/_StarLight/Railroading/metabolize/fax_based.yml new file mode 100644 index 000000000000..c12e175e6047 --- /dev/null +++ b/Resources/Prototypes/_StarLight/Railroading/metabolize/fax_based.yml @@ -0,0 +1,61 @@ +# Conditions + +- type: entity + id: CrewCondition + categories: [ HideSpawnMenu ] + abstract: true + components: + - type: Conditions + conditions: + - !type:SubjectSpeciesCondition + blacklist: + - Abductor + - Skeleton + +# Example(Smokeable) Prototype + +- type: entity + id: RRCardCriminal + parent: CrewCondition + categories: [ HideSpawnMenu ] + components: + - type: RailroadCard + title: rr-criminal + icon: "" + iconColor: "#fd3f3f" # Antag + color: "#6c15ae" # Mythical + image: /Textures/_Starlight/Railroading/criminal.png + description: rr-criminal-desc + - type: RailroadFaxOnChosen + addresses: + - Captain's Office + - Captain + - Security + - Bridge + - Conference Room + - HoS Office + - Warden's Office + - Warden + - Detective's Office + - Magistrate + letters: + - name: rr-criminal-letter-name + content: rr-criminal-1-letter-content + stampState: paper_stamp-centcom + stampedBy: + - stampedColor: "#006666" + stampedName: rr-nt-isd + - type: RailroadAssignRole + role: RRMindRoleCriminal + - type: RailroadTimerTask + duration: 1200 + - type: RailroadSurviveTask + - type: RailroadAvoidHandcuffsTask + - type: RailroadDeliveryReward + delivery: PackageDeliveryRewardSyndicateLetter + dataset: railroadingDeliveryMessages + wrappedDataset: railroadingDeliveryWrappedMessages + - type: RailroadDonationReward + amount: # 20 min survival + min: 200 + max: 300 \ No newline at end of file diff --git a/Resources/Prototypes/_StarLight/Roles/MindRoles/railroading.yml b/Resources/Prototypes/_StarLight/Roles/MindRoles/railroading.yml new file mode 100644 index 000000000000..a5c7aeb240dc --- /dev/null +++ b/Resources/Prototypes/_StarLight/Roles/MindRoles/railroading.yml @@ -0,0 +1,8 @@ +- type: entity + parent: BaseMindRoleAntag + id: RRMindRoleCriminal + name: Criminal Role + components: + - type: MindRole + exclusiveAntag: true + subtype: role-subtype-traitor \ No newline at end of file diff --git a/Resources/Prototypes/game_presets.yml b/Resources/Prototypes/game_presets.yml index bfd7ff056fbd..de2c1fe27fd4 100644 --- a/Resources/Prototypes/game_presets.yml +++ b/Resources/Prototypes/game_presets.yml @@ -113,6 +113,7 @@ description: secret-description rules: - Secret + - RailroadingMinor # 🌟Starlight🌟 - type: gamePreset id: SecretExtended #For Admin Use: Runs Extended but shows "Secret" in lobby. @@ -166,6 +167,7 @@ - MeteorSwarmScheduler - SpaceTrafficControlEventScheduler - BasicRoundstartVariation + - RailroadingMinor # 🌟Starlight🌟 - type: gamePreset id: Deathmatch diff --git a/Resources/Textures/_Starlight/Railroading/criminal.png b/Resources/Textures/_Starlight/Railroading/criminal.png new file mode 100644 index 000000000000..13a5b1b5617c Binary files /dev/null and b/Resources/Textures/_Starlight/Railroading/criminal.png differ