diff --git a/Content.Client/Nyanotrasen/Mail/MailSystem.cs b/Content.Client/Nyanotrasen/Mail/MailSystem.cs index 51fa44f3a83..b8e926637ff 100644 --- a/Content.Client/Nyanotrasen/Mail/MailSystem.cs +++ b/Content.Client/Nyanotrasen/Mail/MailSystem.cs @@ -1,7 +1,6 @@ using Robust.Client.GameObjects; using Content.Shared.Mail; using Content.Shared.StatusIcon; -using Robust.Client.Utility; using Robust.Shared.Prototypes; namespace Content.Client.Mail @@ -30,17 +29,20 @@ namespace Content.Client.Mail /// public sealed class MailJobVisualizerSystem : VisualizerSystem { - [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly SpriteSystem _spriteSystem = default!; + protected override void OnAppearanceChange(EntityUid uid, MailComponent component, ref AppearanceChangeEvent args) { if (args.Sprite == null) return; - if (args.Component.TryGetData(MailVisuals.JobIcon, out string job)) - { - var jobIcon = _prototype.Index(job); - args.Sprite.LayerSetTexture(MailVisualLayers.JobStamp, jobIcon.Icon.Frame0()); - } + args.Component.TryGetData(MailVisuals.JobIcon, out string job); + + if (!_prototypeManager.TryIndex(job, out var icon)) + return; + + args.Sprite.LayerSetTexture(MailVisualLayers.JobStamp, _spriteSystem.Frame0(icon.Icon)); } } diff --git a/Content.Server/Nyanotrasen/Mail/MailSystem.cs b/Content.Server/Nyanotrasen/Mail/MailSystem.cs index c2459be2907..80056a8bb94 100644 --- a/Content.Server/Nyanotrasen/Mail/MailSystem.cs +++ b/Content.Server/Nyanotrasen/Mail/MailSystem.cs @@ -16,17 +16,18 @@ using Content.Server.Destructible.Thresholds.Behaviors; using Content.Server.Destructible.Thresholds.Triggers; using Content.Server.Fluids.Components; +using Content.Server.Item; using Content.Server.Mail.Components; using Content.Server.Mind; using Content.Server.Nutrition.Components; +using Content.Server.Nutrition.EntitySystems; using Content.Server.Popups; using Content.Server.Power.Components; using Content.Server.Station.Components; using Content.Server.Station.Systems; -using Content.Server.StationRecords.Systems; +using Content.Server.Spawners.EntitySystems; using Content.Shared.Access.Components; using Content.Shared.Access.Systems; -using Content.Shared.Coordinates; using Content.Shared.Damage; using Content.Shared.Emag.Components; using Content.Shared.Destructible; @@ -57,15 +58,17 @@ public sealed class MailSystem : EntitySystem [Dependency] private readonly CargoSystem _cargoSystem = default!; [Dependency] private readonly StationSystem _stationSystem = default!; [Dependency] private readonly ChatSystem _chatSystem = default!; + [Dependency] private readonly OpenableSystem _openable = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly SharedContainerSystem _containerSystem = default!; [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!; [Dependency] private readonly DamageableSystem _damageableSystem = default!; - [Dependency] private readonly StationRecordsSystem _recordsSystem = default!; [Dependency] private readonly MindSystem _mind = default!; - [Dependency] private readonly MetaDataSystem _meta = default!; + [Dependency] private readonly ItemSystem _itemSystem = default!; + [Dependency] private readonly MindSystem _mindSystem = default!; + [Dependency] private readonly MetaDataSystem _metaDataSystem = default!; private ISawmill _sawmill = default!; @@ -75,6 +78,8 @@ public override void Initialize() _sawmill = Logger.GetSawmill("mail"); + SubscribeLocalEvent(OnSpawnPlayer, after: new[] { typeof(SpawnPointSystem) }); + SubscribeLocalEvent(OnRemove); SubscribeLocalEvent(OnUseInHand); SubscribeLocalEvent(OnAfterInteractUsing); @@ -104,6 +109,20 @@ public override void Update(float frameTime) } } + /// + /// Dynamically add the MailReceiver component to appropriate entities. + /// + private void OnSpawnPlayer(PlayerSpawningEvent args) + { + if (args.SpawnResult == null || + args.Job == null ) + { + return; + } + + EnsureComp(args.SpawnResult.Value); + } + private void OnRemove(EntityUid uid, MailComponent component, ComponentRemove args) { // Make sure the priority timer doesn't run. @@ -178,9 +197,15 @@ private void OnAfterInteractUsing(EntityUid uid, MailComponent component, AfterI if (!HasComp(uid)) { - if (idCard.FullName != component.Recipient || idCard.JobTitle != component.RecipientJob) + //if (idCard.FullName != component.Recipient || idCard.JobTitle != component.RecipientJob) + //{ + // _popupSystem.PopupEntity(Loc.GetString("mail-recipient-mismatch"), uid, args.User); + // return; + //} + + if (idCard.FullName != component.Recipient) // Frontier - Only match the name { - _popupSystem.PopupEntity(Loc.GetString("mail-recipient-mismatch"), uid, args.User); + _popupSystem.PopupEntity(Loc.GetString("mail-recipient-mismatch-name"), uid, args.User); return; } @@ -199,15 +224,15 @@ private void OnAfterInteractUsing(EntityUid uid, MailComponent component, AfterI return; } - _popupSystem.PopupEntity(Loc.GetString("mail-unlocked-reward", ("bounty", component.Bounty)), uid, args.User); + //_popupSystem.PopupEntity(Loc.GetString("mail-unlocked-reward", ("bounty", component.Bounty)), uid, args.User); + _popupSystem.PopupEntity(Loc.GetString("mail-unlocked-reward"), uid, args.User); // Frontier - Remove the mention of station income component.IsProfitable = false; + var query = EntityQueryEnumerator(); - while (query.MoveNext(out var oUid, out var oComp)) + while (query.MoveNext(out var station, out var account)) { - // only our main station will have an account anyway so I guess we are just going to add it this way shrug. - - _cargoSystem.UpdateBankAccount(oUid, oComp, component.Bounty); + _cargoSystem.UpdateBankAccount(station, account, component.Bounty); return; } } @@ -251,8 +276,8 @@ public void PenalizeStationFailedDelivery(EntityUid uid, MailComponent component if (!component.IsProfitable) return; - //_chatSystem.TrySendInGameICMessage(uid, Loc.GetString(localizationString, ("credits", component.Penalty)), InGameICChatType.Speak, false); # Dont show message. - //_audioSystem.PlayPvs(component.PenaltySound, uid); # Dont play sound. + //_chatSystem.TrySendInGameICMessage(uid, Loc.GetString(localizationString, ("credits", component.Penalty)), InGameICChatType.Speak, false); // Frontier - Dont show message. + //_audioSystem.PlayPvs(component.PenaltySound, uid); // Frontier - Dont show message. // Frontier - Dont play sound. component.IsProfitable = false; @@ -260,11 +285,12 @@ public void PenalizeStationFailedDelivery(EntityUid uid, MailComponent component _appearanceSystem.SetData(uid, MailVisuals.IsPriorityInactive, true); var query = EntityQueryEnumerator(); - while (query.MoveNext(out var oUid, out var oComp)) + while (query.MoveNext(out var station, out var account)) { - // only our main station will have an account anyway so I guess we are just going to add it this way shrug. + //if (_stationSystem.GetOwningStation(uid) != station) // Frontier - No need for this test + // continue; - //_cargoSystem.UpdateBankAccount(oUid, oComp, component.Penalty); # Dont remove money. + //_cargoSystem.UpdateBankAccount(station, account, component.Penalty); // Frontier - Dont remove money. return; } } @@ -274,8 +300,8 @@ private void OnDestruction(EntityUid uid, MailComponent component, DestructionEv if (component.IsLocked) PenalizeStationFailedDelivery(uid, component, "mail-penalty-lock"); - // if (component.IsEnabled) - // OpenMail(uid, component); # Dont open the mail on destruction. + // if (component.IsEnabled) + // OpenMail(uid, component); // Frontier - Dont open the mail on destruction. UpdateAntiTamperVisuals(uid, false); } @@ -329,7 +355,8 @@ public bool IsEntityFragile(EntityUid uid, int fragileDamageThreshold) // It can be spilled easily and has something to spill. if (HasComp(uid) - && TryComp(uid, out DrinkComponent? drinkComponent) + && TryComp(uid, out var openable) + && !_openable.IsClosed(uid, null, openable) && _solutionContainerSystem.PercentFull(uid) > 0) return true; @@ -399,21 +426,6 @@ public bool TryMatchJobTitleToPrototype(string jobTitle, [NotNullWhen(true)] out return false; } - public bool TryMatchJobTitleToIcon(string jobTitle, [NotNullWhen(true)] out string? jobIcon) - { - foreach (var job in _prototypeManager.EnumeratePrototypes()) - { - if (job.LocalizedName == jobTitle) - { - jobIcon = job.Icon; - return true; - } - } - - jobIcon = null; - return false; - } - /// /// Handle all the gritty details particular to a new mail entity. /// @@ -449,7 +461,8 @@ public void SetupMail(EntityUid uid, MailTeleporterComponent component, MailReci mailComp.RecipientJob = recipient.Job; mailComp.Recipient = recipient.Name; - mailComp.RecipientStation = recipient.Ship; + mailComp.RecipientStation = recipient.Ship; // Frontier + if (mailComp.IsFragile) { mailComp.Bounty += component.FragileBonus; @@ -470,10 +483,9 @@ public void SetupMail(EntityUid uid, MailTeleporterComponent component, MailReci mailComp.priorityCancelToken.Token); } - if (TryMatchJobTitleToIcon(recipient.Job, out string? icon)) - _appearanceSystem.SetData(uid, MailVisuals.JobIcon, icon); + _appearanceSystem.SetData(uid, MailVisuals.JobIcon, recipient.JobIcon); - _meta.SetEntityName(uid, Loc.GetString("mail-item-name-addressed", + _metaDataSystem.SetEntityName(uid, Loc.GetString("mail-item-name-addressed", ("recipient", recipient.Name))); var accessReader = EnsureComp(uid); @@ -541,9 +553,6 @@ public bool TryGetMailRecipientForReceiver(MailReceiverComponent receiver, [NotN && idCard.Comp.FullName != null && idCard.Comp.JobTitle != null) { - HashSet accessTags = access.Tags; - - var mayReceivePriorityMail = true; var stationUid = _stationSystem.GetOwningStation(receiver.Owner); var stationName = string.Empty; if (stationUid is EntityUid station @@ -565,8 +574,13 @@ public bool TryGetMailRecipientForReceiver(MailReceiverComponent receiver, [NotN return false; } + var accessTags = access.Tags; + + var mayReceivePriorityMail = !(_mindSystem.GetMind(receiver.Owner) == null); + recipient = new MailRecipient(idCard.Comp.FullName, idCard.Comp.JobTitle, + idCard.Comp.JobIcon, accessTags, mayReceivePriorityMail, stationName); @@ -585,12 +599,14 @@ public List GetMailRecipientCandidates(EntityUid uid) { List candidateList = new(); var mailLocation = Transform(uid); + foreach (var receiver in EntityQuery()) { - // mail is mapwide now, dont need to check if they are on the same station + var location = Transform(receiver.Owner); // mail is mapwide now, dont need to check if they are on the same station + + //if (location.MapID != mailLocation.MapID) //if (_stationSystem.GetOwningStation(receiver.Owner) != _stationSystem.GetOwningStation(uid)) - // continue; - var location = Transform(receiver.Owner); + //continue; if (location.MapID != mailLocation.MapID) continue; @@ -674,6 +690,8 @@ public void SpawnMail(EntityUid uid, MailTeleporterComponent? component = null) var mail = EntityManager.SpawnEntity(chosenParcel, Transform(uid).Coordinates); SetupMail(mail, component, candidate); + + _tagSystem.AddTag(mail, "Recyclable"); // Frontier - Make it so mail can be destroyed by reclaimer } if (_containerSystem.TryGetContainer(uid, "queued", out var queued)) @@ -704,8 +722,10 @@ public void OpenMail(EntityUid uid, MailComponent? component = null, EntityUid? _handsSystem.PickupOrDrop(user, entity); } + _itemSystem.SetSize(uid, 1); _tagSystem.AddTag(uid, "Trash"); _tagSystem.AddTag(uid, "Recyclable"); + _tagSystem.AddTag(uid, "ClothMade"); // Frontier - Make it so moth can eat open mail. component.IsEnabled = false; UpdateMailTrashState(uid, true); } @@ -725,14 +745,16 @@ public struct MailRecipient { public string Name; public string Job; + public string JobIcon; public HashSet AccessTags; public bool MayReceivePriorityMail; public string Ship; - public MailRecipient(string name, string job, HashSet accessTags, bool mayReceivePriorityMail, string ship) + public MailRecipient(string name, string job, string jobIcon, HashSet accessTags, bool mayReceivePriorityMail, string ship) { Name = name; Job = job; + JobIcon = jobIcon; AccessTags = accessTags; MayReceivePriorityMail = mayReceivePriorityMail; Ship = ship; diff --git a/Resources/Locale/en-US/_Nyano/mail.ftl b/Resources/Locale/en-US/_Nyano/mail.ftl index 9dffa2d6758..36d5ec771d2 100644 --- a/Resources/Locale/en-US/_Nyano/mail.ftl +++ b/Resources/Locale/en-US/_Nyano/mail.ftl @@ -1,4 +1,5 @@ mail-recipient-mismatch = Recipient name or job does not match. +mail-recipient-mismatch-name = Recipient name does not match. mail-invalid-access = Recipient name and job match, but access isn't as expected. mail-locked = The anti-tamper lock hasn't been removed. Tap the recipient's ID. mail-desc-far = A parcel of mail. @@ -8,7 +9,7 @@ mail-desc-priority = The anti-tamper lock's [color=yellow]yellow priority tape[/ mail-desc-priority-inactive = The anti-tamper lock's [color=#886600]yellow priority tape[/color] is inactive. mail-unlocked = Anti-tamper system unlocked. mail-unlocked-by-emag = Anti-tamper system *BZZT*. -mail-unlocked-reward = Anti-tamper system unlocked. {$bounty} spesos have been added to station's account. +mail-unlocked-reward = Anti-tamper system unlocked. mail-penalty-lock = ANTI-TAMPER LOCK BROKEN. STATION BANK ACCOUNT PENALIZED BY {$credits} SPESOS. mail-penalty-fragile = INTEGRITY COMPROMISED. STATION BANK ACCOUNT PENALIZED BY {$credits} SPESOS. mail-penalty-expired = DELIVERY PAST DUE. STATION BANK ACCOUNT PENALIZED BY {$credits} SPESOS. diff --git a/Resources/Prototypes/DeltaV/Entities/Mobs/Player/vulpkanin.yml b/Resources/Prototypes/DeltaV/Entities/Mobs/Player/vulpkanin.yml index 1cda9bedf89..bb5e7a46eb3 100644 --- a/Resources/Prototypes/DeltaV/Entities/Mobs/Player/vulpkanin.yml +++ b/Resources/Prototypes/DeltaV/Entities/Mobs/Player/vulpkanin.yml @@ -26,7 +26,6 @@ - type: CameraRecoil - type: Examiner - type: CanHostGuardian - - type: MailReceiver - type: NpcFactionMember factions: - NanoTrasen diff --git a/Resources/Prototypes/Entities/Mobs/Player/arachnid.yml b/Resources/Prototypes/Entities/Mobs/Player/arachnid.yml index a2c03420c65..b0e7e7314a5 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/arachnid.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/arachnid.yml @@ -11,4 +11,3 @@ damageRecovery: types: Asphyxiation: -0.5 # Recovery will suck without chems - - type: MailReceiver diff --git a/Resources/Prototypes/Entities/Mobs/Player/diona.yml b/Resources/Prototypes/Entities/Mobs/Player/diona.yml index 538ddd4331d..4e7bd7e0c98 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/diona.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/diona.yml @@ -11,4 +11,3 @@ damageRecovery: types: Asphyxiation: -1.0 - - type: MailReceiver diff --git a/Resources/Prototypes/Entities/Mobs/Player/dwarf.yml b/Resources/Prototypes/Entities/Mobs/Player/dwarf.yml index d019957a2a3..ea1069cbaaa 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/dwarf.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/dwarf.yml @@ -3,5 +3,4 @@ name: Urist McHands The Dwarf parent: BaseMobDwarf id: MobDwarf - components: - - type: MailReceiver + diff --git a/Resources/Prototypes/Entities/Mobs/Player/human.yml b/Resources/Prototypes/Entities/Mobs/Player/human.yml index c851e5813a3..142f5ad64d3 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/human.yml @@ -3,8 +3,6 @@ name: Urist McHands parent: BaseMobHuman id: MobHuman - components: - - type: MailReceiver #Syndie - type: entity diff --git a/Resources/Prototypes/Entities/Mobs/Player/moth.yml b/Resources/Prototypes/Entities/Mobs/Player/moth.yml index b07eadaf673..ea01677626d 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/moth.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/moth.yml @@ -3,5 +3,3 @@ name: Urist McFluff parent: BaseMobMoth id: MobMoth - components: - - type: MailReceiver diff --git a/Resources/Prototypes/Entities/Mobs/Player/reptilian.yml b/Resources/Prototypes/Entities/Mobs/Player/reptilian.yml index d3e3ef466b8..cdba2270d49 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/reptilian.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/reptilian.yml @@ -3,6 +3,4 @@ name: Urisst' Mzhand parent: BaseMobReptilian id: MobReptilian - components: - - type: MailReceiver #Weh diff --git a/Resources/Prototypes/Entities/Mobs/Player/slime.yml b/Resources/Prototypes/Entities/Mobs/Player/slime.yml index aff8b377bfe..4e5974b3084 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/slime.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/slime.yml @@ -2,5 +2,3 @@ save: false parent: BaseMobSlimePerson id: MobSlimePerson - components: - - type: MailReceiver diff --git a/Resources/Prototypes/Entities/Mobs/Player/vox.yml b/Resources/Prototypes/Entities/Mobs/Player/vox.yml index 318e4df058e..de1e3da2be7 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/vox.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/vox.yml @@ -3,5 +3,3 @@ name: Vox parent: BaseMobVox id: MobVox - components: - - type: MailReceiver diff --git a/Resources/Prototypes/_Nyano/Entities/Mobs/Player/felinid.yml b/Resources/Prototypes/_Nyano/Entities/Mobs/Player/felinid.yml index 37c3fb47557..6147037ced1 100644 --- a/Resources/Prototypes/_Nyano/Entities/Mobs/Player/felinid.yml +++ b/Resources/Prototypes/_Nyano/Entities/Mobs/Player/felinid.yml @@ -3,12 +3,3 @@ name: Urist McFelinid parent: [MobFelinidBase, BaseMob] id: MobFelinid - components: - - type: Respirator - damage: - types: - Asphyxiation: 1.0 - damageRecovery: - types: - Asphyxiation: -1.0 - - type: MailReceiver diff --git a/Resources/Prototypes/_Nyano/Entities/Mobs/Player/oni.yml b/Resources/Prototypes/_Nyano/Entities/Mobs/Player/oni.yml index 0c46ac07411..075555f9b12 100644 --- a/Resources/Prototypes/_Nyano/Entities/Mobs/Player/oni.yml +++ b/Resources/Prototypes/_Nyano/Entities/Mobs/Player/oni.yml @@ -3,12 +3,3 @@ name: Urist McOni parent: [MobOniBase, BaseMob] id: MobOni - components: - - type: Respirator - damage: - types: - Asphyxiation: 1.0 - damageRecovery: - types: - Asphyxiation: -1.0 - - type: MailReceiver diff --git a/Resources/Prototypes/_Nyano/Entities/Objects/Specific/Mail/base_mail.yml b/Resources/Prototypes/_Nyano/Entities/Objects/Specific/Mail/base_mail.yml index 7c7c765c7cf..3924a690a86 100644 --- a/Resources/Prototypes/_Nyano/Entities/Objects/Specific/Mail/base_mail.yml +++ b/Resources/Prototypes/_Nyano/Entities/Objects/Specific/Mail/base_mail.yml @@ -18,7 +18,6 @@ map: ["enum.MailVisualLayers.FragileStamp"] visible: false - map: ["enum.MailVisualLayers.JobStamp"] - sprite: Interface/Misc/job_icons.rsi scale: 0.5, 0.5 offset: 0.275, 0.2 - state: locked @@ -96,8 +95,17 @@ - type: DamageOtherOnHit damage: types: - Blunt: 5 + Blunt: 1 # Frontier - 5<1, death by 1000 cuts. - type: CargoSellBlacklist + - type: Food # Frontier - Moth food + requiresSpecialDigestion: true + - type: SolutionContainerManager + solutions: + food: + maxVol: 1 + reagents: + - ReagentId: Nothing + Quantity: 1 # This empty parcel is allowed to exist and evade the tests for the admin # mailto command.