diff --git a/Content.Client/_Sunrise/Disease/DiseaseRoleSystem.cs b/Content.Client/_Sunrise/Disease/DiseaseRoleSystem.cs new file mode 100644 index 00000000000..dede9bc65a1 --- /dev/null +++ b/Content.Client/_Sunrise/Disease/DiseaseRoleSystem.cs @@ -0,0 +1,33 @@ +using Content.Shared.Humanoid; +using Content.Shared._Sunrise.Disease; +namespace Content.Client._Sunrise.Disease; + +public sealed class DiseaseRoleSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeNetworkEvent(OnInfect); + } + + + + private void OnInfect(ClientInfectEvent ev) + { + + var target = GetEntity(ev.Infected); + var performer = GetEntity(ev.Owner); + + if (!TryComp(target, out var body)) + return; + + var sick = EnsureComp(target); + sick.owner = performer; + sick.Inited = true; + if (TryComp(performer, out var comp)) + { + comp.Infected.Add(target); + } + } + +} diff --git a/Content.Client/_Sunrise/Disease/SickSystem.cs b/Content.Client/_Sunrise/Disease/SickSystem.cs new file mode 100644 index 00000000000..6cc44aadfa9 --- /dev/null +++ b/Content.Client/_Sunrise/Disease/SickSystem.cs @@ -0,0 +1,49 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Shared.Mind.Components; +using Content.Shared.Mobs.Systems; +using Content.Shared.NPC; +using Content.Shared.StatusIcon; +using Content.Shared.StatusIcon.Components; +using Robust.Client.Player; +using Robust.Shared.Prototypes; +using Content.Shared._Sunrise.Disease; +using Content.Shared.Ghost; +namespace Content.Client._Sunrise.Disease; +public sealed class SickSystem : EntitySystem +{ + [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly IPlayerManager _playerManager = default!; + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnGetStatusIcon); + SubscribeNetworkEvent(OnUpdateInfect); + } + + private void OnUpdateInfect(UpdateInfectionsEvent args) + { + EnsureComp(GetEntity(args.Uid)).Inited = true; + } + + private void OnGetStatusIcon(EntityUid uid, SickComponent component, ref GetStatusIconsEvent args) + { + if (component.Inited) + { + if (_playerManager.LocalEntity != null) + { + if (HasComp(_playerManager.LocalEntity.Value) || HasComp(_playerManager.LocalEntity.Value)) + { + if (!_mobState.IsDead(uid) && + !HasComp(uid) && + TryComp(uid, out var mindContainer) && + mindContainer.ShowExamineInfo) + { + args.StatusIcons.Add(_prototype.Index(component.Icon)); + } + } + } + } + } +} diff --git a/Content.Client/_Sunrise/Disease/VaccinatorSystem.cs b/Content.Client/_Sunrise/Disease/VaccinatorSystem.cs new file mode 100644 index 00000000000..e553646f095 --- /dev/null +++ b/Content.Client/_Sunrise/Disease/VaccinatorSystem.cs @@ -0,0 +1,10 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Shared.Chemistry.EntitySystems; + +namespace Content.Client.Chemistry.EntitySystems; + +/// +public sealed class VaccinatorSystem : SharedVaccinatorSystem +{ + +} diff --git a/Content.Server/Traits/Assorted/NarcolepsyComponent.cs b/Content.Server/Traits/Assorted/NarcolepsyComponent.cs index c8926552bc0..44a96bdce50 100644 --- a/Content.Server/Traits/Assorted/NarcolepsyComponent.cs +++ b/Content.Server/Traits/Assorted/NarcolepsyComponent.cs @@ -1,4 +1,4 @@ -using System.Numerics; +using System.Numerics; namespace Content.Server.Traits.Assorted; @@ -12,13 +12,13 @@ public sealed partial class NarcolepsyComponent : Component /// The random time between incidents, (min, max). /// [DataField("timeBetweenIncidents", required: true)] - public Vector2 TimeBetweenIncidents { get; set; } // Sunrise-Edit + public Vector2 TimeBetweenIncidents = new Vector2(300, 600); /// /// The duration of incidents, (min, max). /// [DataField("durationOfIncident", required: true)] - public Vector2 DurationOfIncident { get; set; } // Sunrise-Edit + public Vector2 DurationOfIncident = new Vector2(10, 30); public float NextIncidentTime; } diff --git a/Content.Server/Traits/Assorted/NarcolepsySystem.cs b/Content.Server/Traits/Assorted/NarcolepsySystem.cs index b001ceb6164..893e440dae0 100644 --- a/Content.Server/Traits/Assorted/NarcolepsySystem.cs +++ b/Content.Server/Traits/Assorted/NarcolepsySystem.cs @@ -2,6 +2,7 @@ using Content.Shared.Bed.Sleep; using Content.Shared.StatusEffect; using Robust.Shared.Random; +using System.Numerics; namespace Content.Server.Traits.Assorted; @@ -36,6 +37,14 @@ public void AdjustNarcolepsyTimer(EntityUid uid, int TimerReset, NarcolepsyCompo narcolepsy.NextIncidentTime = TimerReset; } + public void SetNarcolepsy(EntityUid uid, Vector2 timeBetweenIncidents, Vector2 durationOfIncident, NarcolepsyComponent? narcolepsy = null) + { + if (!Resolve(uid, ref narcolepsy, false)) + return; + narcolepsy.DurationOfIncident = durationOfIncident; + narcolepsy.TimeBetweenIncidents = timeBetweenIncidents; + } + public override void Update(float frameTime) { base.Update(frameTime); diff --git a/Content.Server/_Sunrise/Disease/CureDiseaseInfection.cs b/Content.Server/_Sunrise/Disease/CureDiseaseInfection.cs new file mode 100644 index 00000000000..082747bc85c --- /dev/null +++ b/Content.Server/_Sunrise/Disease/CureDiseaseInfection.cs @@ -0,0 +1,33 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Shared.Chemistry.Reagent; +using Robust.Shared.Prototypes; +using Content.Shared._Sunrise.Disease; +using Content.Shared.EntityEffects; +public sealed partial class CureDiseaseInfection : EntityEffect +{ + [DataField] + public bool Innoculate; + + protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) + { + if (Innoculate) + return "ок"; + + return "окей"; + } + + public override void Effect(EntityEffectBaseArgs args) + { + var entityManager = args.EntityManager; + if (!entityManager.HasComponent(args.TargetEntity)) return; + if (entityManager.TryGetComponent(args.TargetEntity, out var sick)) + { + if (entityManager.TryGetComponent(sick.owner, out var disease)) + { + var comp = entityManager.EnsureComponent(args.TargetEntity); + comp.Immune = Innoculate; + comp.Delay = TimeSpan.FromMinutes(2) + TimeSpan.FromSeconds(disease.Shield * 30); + } + } + } +} diff --git a/Content.Server/_Sunrise/Disease/DiseaseImmuneClothingSystem.cs b/Content.Server/_Sunrise/Disease/DiseaseImmuneClothingSystem.cs new file mode 100644 index 00000000000..d3a826593b4 --- /dev/null +++ b/Content.Server/_Sunrise/Disease/DiseaseImmuneClothingSystem.cs @@ -0,0 +1,59 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Shared.Clothing.Components; +using Content.Shared.Inventory.Events; +using Content.Shared._Sunrise.Disease; +using Content.Shared.Examine; +using Content.Shared.Verbs; +using Robust.Shared.Utility; +namespace Content.Server._Sunrise.Disease; + +public sealed class DiseaseImmuneClothingSystem : EntitySystem +{ + [Dependency] private readonly ExamineSystemShared _examine = default!; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnGotEquipped); + SubscribeLocalEvent(OnGotUnequipped); + SubscribeLocalEvent>(OnArmorVerbExamine); + } + + private void OnGotEquipped(EntityUid uid, DiseaseImmuneClothingComponent component, GotEquippedEvent args) + { + if (!TryComp(uid, out ClothingComponent? clothing)) + return; + var isCorrectSlot = clothing.Slots.HasFlag(args.SlotFlags); + if (!isCorrectSlot) + return; + + EnsureComp(args.Equipee).Prob += component.Prob; + if (Comp(args.Equipee).Prob > 1) Comp(args.Equipee).Prob = 1; + + component.IsActive = true; + } + + private void OnGotUnequipped(EntityUid uid, DiseaseImmuneClothingComponent component, GotUnequippedEvent args) + { + if (!component.IsActive) + return; + + EnsureComp(args.Equipee).Prob -= component.Prob; + if (Comp(args.Equipee).Prob < 0) Comp(args.Equipee).Prob = 0; + + component.IsActive = false; + } + + private void OnArmorVerbExamine(EntityUid uid, DiseaseImmuneClothingComponent component, GetVerbsEvent args) + { + if (!args.CanInteract || !args.CanAccess) + return; + + var examineMarkup = new FormattedMessage(); + examineMarkup.TryAddMarkup($"Защищает от заражения на {Convert.ToInt32(component.Prob * 100)}%", out var _); + + _examine.AddDetailedExamineVerb(args, component, examineMarkup, + "Стерильность", "/Textures/Interface/VerbIcons/dot.svg.192dpi.png", + "Изучить показатели стерильности."); + } + +} diff --git a/Content.Server/_Sunrise/Disease/DiseaseRoleSystem.cs b/Content.Server/_Sunrise/Disease/DiseaseRoleSystem.cs new file mode 100644 index 00000000000..a03e1871fe3 --- /dev/null +++ b/Content.Server/_Sunrise/Disease/DiseaseRoleSystem.cs @@ -0,0 +1,241 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Shared.Actions; +using Robust.Shared.Random; +using Content.Shared._Sunrise.Disease; +using Content.Server.Store.Systems; +using Robust.Shared.Prototypes; +using Content.Shared.FixedPoint; +using Content.Shared.Popups; +using Content.Shared.Store.Components; +using Content.Server.Objectives; +using Content.Server.GameTicking; +using Content.Shared.Random.Helpers; + +namespace Content.Server._Sunrise.Disease; + +public sealed class DiseaseRoleSystem : SharedDiseaseRoleSystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SharedActionsSystem _actionsSystem = default!; + [Dependency] private readonly StoreSystem _store = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + + + [ValidatePrototypeId] private const string DiseaseShopId = "ActionDiseaseShop"; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnShop); + SubscribeLocalEvent(OnAddSymptom); + SubscribeLocalEvent(OnInfects); + + SubscribeLocalEvent(OnBaseChance); + SubscribeLocalEvent(OnCoughChance); + SubscribeLocalEvent(OnLethal); + SubscribeLocalEvent(OnShield); + SubscribeLocalEvent(OnObjectivesTextGetInfo); + SubscribeLocalEvent(OnRoundEndText); + } + + + private void OnRoundEndText(RoundEndTextAppendEvent ev) + { + var sick = EntityQueryEnumerator(); + var immune = EntityQueryEnumerator(); + var disease = EntityQueryEnumerator(); + int infected = 0; + int immuned = 0; + int infects = 0; + while (sick.MoveNext(out _)) + { + infects++; + } + while (immune.MoveNext(out _)) + { + immuned++; + } + while (disease.MoveNext(out var comp)) + { + infected = comp.SickOfAllTime; + } + ev.AddLine(Loc.GetString("disease-round-end-result")); + ev.AddLine(Loc.GetString("disease-round-end-result-infected", ("count", infected))); + ev.AddLine(Loc.GetString("disease-round-end-result-infects", ("count", infects))); + ev.AddLine(Loc.GetString("disease-round-end-result-immuned", ("count", immuned))); + } + private void OnObjectivesTextGetInfo(EntityUid uid, DiseaseRuleComponent comp, ref ObjectivesTextGetInfoEvent args) + { + args.Minds = comp.DiseasesMinds; + args.AgentName = "разумная болезнь"; + } + + + private void OnLethal(EntityUid uid, DiseaseRoleComponent component, DiseaseAddLethalEvent args) + { + if (!TryRemoveMoney(uid, 15)) + { + _popup.PopupEntity($"Вам не хватает очков эволюции", uid, uid); + return; + } + component.Lethal += 1; + if (component.Lethal >= 5) + { + _actionsSystem.RemoveAction(uid, args.Action); + } + } + + private void OnShield(EntityUid uid, DiseaseRoleComponent component, DiseaseAddShieldEvent args) + { + if (!TryRemoveMoney(uid, 15)) + { + _popup.PopupEntity($"Вам не хватает очков эволюции", uid, uid); + return; + } + component.Shield += 1; + if (component.Shield >= 6) + { + _actionsSystem.RemoveAction(uid, args.Action); + } + } + + private void OnBaseChance(EntityUid uid, DiseaseRoleComponent component, DiseaseAddBaseChanceEvent args) + { + if (!TryRemoveMoney(uid, 20)) + { + _popup.PopupEntity($"Вам не хватает очков эволюции", uid, uid); + return; + } + if (component.BaseInfectChance < 0.9f) + component.BaseInfectChance += 0.1f; + else + { + component.BaseInfectChance = 1; + _actionsSystem.RemoveAction(uid, args.Action); + } + } + + private void OnCoughChance(EntityUid uid, DiseaseRoleComponent component, DiseaseAddCoughChanceEvent args) + { + if (!TryRemoveMoney(uid, 15)) + { + _popup.PopupEntity($"Вам не хватает очков эволюции", uid, uid); + return; + } + if (component.CoughInfectChance < 0.85f) + component.CoughInfectChance += 0.05f; + else + { + component.CoughInfectChance = 1; + _actionsSystem.RemoveAction(uid, args.Action); + } + } + + + private void OnInfects(InfectEvent args) + { + if (TryComp(args.Performer, out var component)) + { + if (component.FreeInfects > 0) + { + component.FreeInfects--; + OnInfect(args, 1); + } + else if (TryRemoveMoney(args.Performer, component.InfectCost)) + { + OnInfect(args); + } + } + } + + private void OnInit(EntityUid uid, DiseaseRoleComponent component, ComponentInit args) + { + + foreach (var (id, charges) in component.Actions) + { + EntityUid? actionId = null; + if (_actionsSystem.AddAction(uid, ref actionId, id)) + _actionsSystem.SetCharges(actionId, charges < 0 ? null : charges); + } + component.NewBloodReagent = _random.Pick(new List() { "DiseaseBloodFirst", "DiseaseBloodSecond", "DiseaseBloodThird" }); + component.Symptoms.Add("Headache", (1, 4)); + } + + private void OnMapInit(EntityUid uid, DiseaseRoleComponent component, MapInitEvent args) + { + _actionsSystem.AddAction(uid, DiseaseShopId, uid); + } + + private void OnShop(EntityUid uid, DiseaseRoleComponent component, DiseaseShopActionEvent args) + { + if (!TryComp(uid, out var store)) + return; + _store.ToggleUi(uid, uid, store); + } + + void AddMoney(EntityUid uid, FixedPoint2 value) + { + if (TryComp(uid, out var diseaseComp)) + { + if (TryComp(uid, out var store)) + { + bool f = _store.TryAddCurrency(new Dictionary + { + {diseaseComp.CurrencyPrototype, value} + }, uid); + _store.UpdateUserInterface(uid, uid, store); + } + } + } + + bool TryRemoveMoney(EntityUid uid, FixedPoint2 value) + { + if (TryComp(uid, out var diseaseComp)) + { + if (TryComp(uid, out var store)) + { + if (store.Balance[diseaseComp.CurrencyPrototype] >= value) + { + _store.TryAddCurrency(new Dictionary + { + {diseaseComp.CurrencyPrototype, -value} + }, uid); + _store.UpdateUserInterface(uid, uid, store); + return true; + } + else + { + return false; + } + } + } + return false; + } + + private void OnAddSymptom(EntityUid uid, DiseaseRoleComponent component, DiseaseAddSymptomEvent args) + { + if (!component.Symptoms.ContainsKey(args.Symptom)) + { + component.Symptoms.Add(args.Symptom, (args.MinLevel, args.MaxLevel)); + } + _actionsSystem.RemoveAction(uid, args.Action); + } + + //private void OnZombie(EntityUid uid, DiseaseRoleComponent component, DiseaseZombieEvent args) + //{ + // var inf = component.Infected.ToArray(); + // foreach(EntityUid infected in inf) + // { + // if (_random.Prob(0.8f)) { + // RemComp(infected); + // component.Infected.Remove(infected); + // EnsureComp(infected); + // EnsureComp(infected); + // } + // } + //} + +} diff --git a/Content.Server/_Sunrise/Disease/DiseaseRuleComponent.cs b/Content.Server/_Sunrise/Disease/DiseaseRuleComponent.cs new file mode 100644 index 00000000000..8031ee0f3e6 --- /dev/null +++ b/Content.Server/_Sunrise/Disease/DiseaseRuleComponent.cs @@ -0,0 +1,7 @@ +namespace Content.Server._Sunrise.Disease; + +[RegisterComponent, Access(typeof(DiseaseRoleSystem))] +public sealed partial class DiseaseRuleComponent : Component +{ + public List<(EntityUid, string)> DiseasesMinds = new(); +} diff --git a/Content.Server/_Sunrise/Disease/MinimumBleedComponent.cs b/Content.Server/_Sunrise/Disease/MinimumBleedComponent.cs new file mode 100644 index 00000000000..2c7e4859677 --- /dev/null +++ b/Content.Server/_Sunrise/Disease/MinimumBleedComponent.cs @@ -0,0 +1,12 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Shared.StatusIcon; +using Robust.Shared.GameStates; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Server._Sunrise.Disease; + +[RegisterComponent] +public sealed partial class MinimumBleedComponent : Component +{ + [DataField] public float MinValue = 1f; +} diff --git a/Content.Server/_Sunrise/Disease/MinimumBleedSystem.cs b/Content.Server/_Sunrise/Disease/MinimumBleedSystem.cs new file mode 100644 index 00000000000..51db5b6b79e --- /dev/null +++ b/Content.Server/_Sunrise/Disease/MinimumBleedSystem.cs @@ -0,0 +1,42 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Robust.Shared.Configuration; +namespace Content.Server._Sunrise.Disease; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; +using Content.Server.Body.Components; +using Content.Server.Body.Systems; +using Content.Server.Chat.Systems; +using Robust.Server.GameObjects; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Map; +using Robust.Shared.Random; +using Content.Server.Store.Systems; +using Content.Server.Popups; +using Content.Shared.Damage; +using Content.Shared.Mobs.Systems; +using Content.Server.Medical; +public sealed class MinimumBleedSystem : EntitySystem +{ + [Dependency] private readonly BloodstreamSystem _bloodstream = default!; + public override void Initialize() + { + base.Initialize(); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var component)) + { + if (TryComp(uid, out var blood)) + { + if (blood.BleedAmount < component.MinValue) + { + _bloodstream.TryModifyBleedAmount(uid, component.MinValue, blood); + } + } + } + } +} diff --git a/Content.Server/_Sunrise/Disease/SickSystem.cs b/Content.Server/_Sunrise/Disease/SickSystem.cs new file mode 100644 index 00000000000..016e6d3f484 --- /dev/null +++ b/Content.Server/_Sunrise/Disease/SickSystem.cs @@ -0,0 +1,299 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; +using Content.Shared._Sunrise.Disease; +using System.Numerics; +using Content.Server.Body.Components; +using Content.Server.Body.Systems; +using Content.Server.Chat.Systems; +using Content.Shared.Interaction.Events; +using Robust.Server.GameObjects; +using Robust.Shared.Map; +using Robust.Shared.Random; +using Content.Shared.Humanoid; +using Content.Server.Store.Components; +using Content.Server.Store.Systems; +using Content.Server.Popups; +using Content.Shared.Popups; +using Content.Server.Chat; +using Content.Shared.Stunnable; +using Content.Shared.Damage.Prototypes; +using Content.Shared.Damage; +using Content.Server.Emoting.Systems; +using Content.Server.Speech.EntitySystems; +using Content.Shared.FixedPoint; +using Content.Server.Medical; +using Content.Server.Traits.Assorted; +using Content.Shared.Traits.Assorted; +using Content.Shared.Eye.Blinding.Components; +using Content.Shared.Item; +using Content.Shared.Speech.Muting; +using Content.Shared.Store.Components; +namespace Content.Server._Sunrise.Disease; +public sealed class SickSystem : SharedSickSystem +{ + [Dependency] private readonly AutoEmoteSystem _autoEmote = default!; + [Dependency] private readonly StoreSystem _store = default!; + [Dependency] private readonly IRobustRandom _robustRandom = default!; + [Dependency] private readonly IServerEntityManager _entityManager = default!; + [Dependency] private readonly VomitSystem _vomitSystem = default!; + [Dependency] private readonly BloodstreamSystem _bloodstream = default!; + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly DamageableSystem _damageableSystem = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly SharedStunSystem _stun = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + private EntityLookupSystem _lookup => _entityManager.System(); + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnShut); + SubscribeLocalEvent(OnEmote, before: + new[] { typeof(VocalSystem), typeof(BodyEmotesSystem) }); + } + + public void OnShut(EntityUid uid, SickComponent component, ComponentShutdown args) + { + foreach (var emote in EnsureComp(uid).Emotes) + { + if (emote.Contains("Infected")) + { + _autoEmote.RemoveEmote(uid, emote); + } + } + foreach (var key in component.Symptoms) + { + switch (key) + { + case "Narcolepsy": + if (TryComp(uid, out var narc)) + { + RemComp(uid); + } + break; + case "Muted": + if (TryComp(uid, out var mute)) + { + RemComp(uid); + } + break; + case "Blindness": + if (TryComp(uid, out var blind)) + { + RemComp(uid); + } + if (HasComp(uid)) + { + RemComp(uid); + } + if (HasComp(uid)) + { + RemComp(uid); + } + break; + case "Slowness": + if (TryComp(uid, out var slow)) + { + RemComp(uid); + } + break; + case "Bleed": + if (TryComp(uid, out var bleed)) + { + RemComp(uid); + } + break; + } + } + _bloodstream.ChangeBloodReagent(uid, component.BeforeInfectedBloodReagent); + } + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var component)) + { + if (TryComp(component.owner, out var diseaseComp)) + { + UpdateInfection(uid, component, component.owner, diseaseComp); + if (!component.Inited) + { + //Infect + if (TryComp(uid, out var stream)) + component.BeforeInfectedBloodReagent = stream.BloodReagent; + _bloodstream.ChangeBloodReagent(uid, diseaseComp.NewBloodReagent); + + RaiseNetworkEvent(new ClientInfectEvent(GetNetEntity(uid), GetNetEntity(component.owner))); + diseaseComp.SickOfAllTime++; + AddMoney(uid, 5); + + component.Inited = true; + } + else + { + if (_gameTiming.CurTime >= component.NextStadyAt) + { + component.Stady++; + foreach (var emote in EnsureComp(uid).Emotes) + { + if (emote.Contains("Infected")) + { + _autoEmote.RemoveEmote(uid, emote); + } + } + component.Symptoms.Clear(); + component.NextStadyAt = _gameTiming.CurTime + component.StadyDelay; + } + } + } + } + } + + void AddMoney(EntityUid uid, FixedPoint2 value) + { + if (TryComp(uid, out var component)) + { + if (TryComp(component.owner, out var diseaseComp)) + { + if (TryComp(component.owner, out var store)) + { + bool f = _store.TryAddCurrency(new Dictionary + { + {diseaseComp.CurrencyPrototype, value} + }, component.owner); + _store.UpdateUserInterface(component.owner, component.owner, store); + } + } + } + } + + private void UpdateInfection(EntityUid uid, SickComponent component, EntityUid disease, DiseaseRoleComponent diseaseComponent) + { + foreach ((var key, (var min, var max)) in diseaseComponent.Symptoms) + { + if (!component.Symptoms.Contains(key)) + { + if (component.Stady >= min && component.Stady <= max) + { + component.Symptoms.Add(key); + EnsureComp(uid); + switch (key) + { + case "Headache": + _autoEmote.AddEmote(uid, "InfectedHeadache"); + break; + case "Cough": + _autoEmote.AddEmote(uid, "InfectedCough"); + break; + case "Sneeze": + _autoEmote.AddEmote(uid, "InfectedSneeze"); + break; + case "Vomit": + _autoEmote.AddEmote(uid, "InfectedVomit"); + break; + case "Crying": + _autoEmote.AddEmote(uid, "InfectedCrying"); + break; + case "Narcolepsy": + if (!HasComp(uid)) + { + var c = AddComp(uid); + EntityManager.EntitySysManager.GetEntitySystem().SetNarcolepsy(uid, new Vector2(10, 30), new Vector2(300, 600), c); + } + break; + case "Muted": + EnsureComp(uid); + break; + case "Blindness": + EnsureComp(uid); + break; + case "Slowness": + EnsureComp(uid); + break; + case "Bleed": + EnsureComp(uid); + break; + case "Insult": + _autoEmote.AddEmote(uid, "InfectedInsult"); + break; + } + } + } + } + } + + private void OnEmote(EntityUid uid, SickComponent component, ref EmoteEvent args) + { + if (args.Handled) + return; + if (!component.Symptoms.Contains(args.Emote.ID)) return; + switch (args.Emote.ID) + { + case "Headache": + _popupSystem.PopupEntity("Вы чувствуете лёгкую головную боль.", uid, uid, PopupType.Small); + break; + case "Cough": + if (_robustRandom.Prob(0.9f)) + { + if (TryComp(component.owner, out var disease)) + { + var kind = SuicideKind.Piercing; + if (_prototypeManager.TryIndex(kind.ToString(), out var damagePrototype)) + { + _damageableSystem.TryChangeDamage(uid, new(damagePrototype, 0.25f * disease.Lethal), true, origin: uid); + } + + foreach (var entity in _lookup.GetEntitiesInRange(uid, 0.7f)) + { + if (_robustRandom.Prob(disease.CoughInfectChance)) + { + if (HasComp(entity) && !HasComp(entity) && !HasComp(entity)) + { + OnInfected(entity, component.owner, Comp(component.owner).CoughInfectChance); + } + } + } + } + } + break; + case "Sneeze": + if (_robustRandom.Prob(0.9f)) + { + if (TryComp(component.owner, out var disease)) + { + foreach (var entity in _lookup.GetEntitiesInRange(uid, 1.2f)) + { + if (_robustRandom.Prob(disease.CoughInfectChance)) + { + if (HasComp(entity) && !HasComp(entity) && !HasComp(entity)) + { + OnInfected(entity, component.owner, Comp(component.owner).CoughInfectChance); + } + } + } + } + } + break; + case "Vomit": + if (_robustRandom.Prob(0.4f)) + { + _vomitSystem.Vomit(uid, -30, -20); + } + break; + case "Insult": + if (TryComp(component.owner, out var dis)) + { + _stun.TryParalyze(uid, TimeSpan.FromSeconds(5), false); + var kind = SuicideKind.Shock; + if (_prototypeManager.TryIndex(kind.ToString(), out var damagePrototype)) + { + _damageableSystem.TryChangeDamage(uid, new(damagePrototype, 0.35f * dis.Lethal), true, origin: uid); + } + } + break; + } + } +} diff --git a/Content.Server/_Sunrise/Disease/SleepyComponent.cs b/Content.Server/_Sunrise/Disease/SleepyComponent.cs new file mode 100644 index 00000000000..744eb0ec77b --- /dev/null +++ b/Content.Server/_Sunrise/Disease/SleepyComponent.cs @@ -0,0 +1,16 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using System.Numerics; + +namespace Content.Server.Traits.Assorted; + +[RegisterComponent, Access(typeof(NarcolepsySystem), typeof(SleepySystem))] +public sealed partial class SleepyComponent : Component +{ + [DataField("timeBetweenIncidents", required: true)] + public Vector2 TimeBetweenIncidents = new Vector2(300, 600); + + [DataField("durationOfIncident", required: true)] + public Vector2 DurationOfIncident = new Vector2(10, 30); + + public float NextIncidentTime; +} diff --git a/Content.Server/_Sunrise/Disease/SleepySystem.cs b/Content.Server/_Sunrise/Disease/SleepySystem.cs new file mode 100644 index 00000000000..eeb70752299 --- /dev/null +++ b/Content.Server/_Sunrise/Disease/SleepySystem.cs @@ -0,0 +1,68 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Shared.Bed.Sleep; +using Content.Shared.StatusEffect; +using Robust.Shared.Random; +using System.Numerics; + +namespace Content.Server.Traits.Assorted; + +public sealed class SleepySystem : EntitySystem +{ + [ValidatePrototypeId] + private const string StatusEffectKey = "ForcedSleep"; // Same one used by N2O and other sleep chems. + + [Dependency] private readonly StatusEffectsSystem _statusEffects = default!; + [Dependency] private readonly IRobustRandom _random = default!; + public override void Initialize() + { + SubscribeLocalEvent(SetupNarcolepsy); + } + + private void SetupNarcolepsy(EntityUid uid, SleepyComponent component, ComponentStartup args) + { + component.NextIncidentTime = + _random.NextFloat(component.TimeBetweenIncidents.X, component.TimeBetweenIncidents.Y); + } + + public void AdjustNarcolepsyTimer(EntityUid uid, int TimerReset, SleepyComponent? narcolepsy = null) + { + if (!Resolve(uid, ref narcolepsy, false)) + return; + + narcolepsy.NextIncidentTime = TimerReset; + } + + public void SetNarcolepsy(EntityUid uid, Vector2 timeBetweenIncidents, Vector2 durationOfIncident, SleepyComponent? narcolepsy = null) + { + if (!Resolve(uid, ref narcolepsy, false)) + return; + narcolepsy.DurationOfIncident = durationOfIncident; + narcolepsy.TimeBetweenIncidents = timeBetweenIncidents; + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var narcolepsy)) + { + narcolepsy.NextIncidentTime -= frameTime; + + if (narcolepsy.NextIncidentTime >= 0) + continue; + + // Set the new time. + narcolepsy.NextIncidentTime += + _random.NextFloat(narcolepsy.TimeBetweenIncidents.X, narcolepsy.TimeBetweenIncidents.Y); + + var duration = _random.NextFloat(narcolepsy.DurationOfIncident.X, narcolepsy.DurationOfIncident.Y); + + // Make sure the sleep time doesn't cut into the time to next incident. + narcolepsy.NextIncidentTime += duration; + + _statusEffects.TryAddStatusEffect(uid, StatusEffectKey, + TimeSpan.FromSeconds(duration), false); + } + } +} diff --git a/Content.Server/_Sunrise/Disease/VaccinatorSystem.cs b/Content.Server/_Sunrise/Disease/VaccinatorSystem.cs new file mode 100644 index 00000000000..ab9a74a6ef3 --- /dev/null +++ b/Content.Server/_Sunrise/Disease/VaccinatorSystem.cs @@ -0,0 +1,148 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Server.Power.Components; +using Content.Server.Power.EntitySystems; +using Content.Shared.Chemistry.Components; +using Content.Shared.Chemistry.EntitySystems; +using Content.Server.Paper; +using Content.Shared.Chemistry.Components; +using Content.Shared.Chemistry.Reaction; +using Content.Shared.Interaction; +using Content.Shared.Popups; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Containers; +using Robust.Shared.Network; +using Robust.Shared.Timing; +using System.Collections.Frozen; +using Content.Shared.Paper; +using Robust.Shared.Utility; +using static Content.Shared.Paper.PaperComponent; +using Robust.Shared.Prototypes; +using System.Linq; +using Robust.Shared.Serialization; +using Content.Shared.Chemistry.Reagent; +using System.Linq; +using System.Text; +namespace Content.Server.Chemistry.EntitySystems; + +/// +public sealed class VaccinatorSystem : SharedVaccinatorSystem +{ + /// + /// + [Dependency] private readonly PaperSystem _paperSystem = default!; + [Dependency] private readonly MetaDataSystem _metaData = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + + /// + /// A cache of all reactions indexed by at most ONE of their required reactants. + /// I.e., even if a reaction has more than one reagent, it will only ever appear once in this dictionary. + /// + private FrozenDictionary> _reactionsSingle = default!; + + /// + /// A cache of all reactions indexed by one of their required reactants. + /// + private FrozenDictionary> _reactions = default!; + + + + public override void Initialize() + { + base.Initialize(); + InitializeReactionCache(); + + SubscribeLocalEvent(OnPowerChanged); + SubscribeNetworkEvent(OnPaper); + } + + + /// + /// Handles building the reaction cache. + /// + private void InitializeReactionCache() + { + // Construct single-reaction dictionary. + var dict = new Dictionary>(); + foreach (var reaction in _prototypeManager.EnumeratePrototypes()) + { + // For this dictionary we only need to cache based on the first reagent. + var reagent = reaction.Reactants.Keys.First(); + var list = dict.GetOrNew(reagent); + list.Add(reaction); + } + _reactionsSingle = dict.ToFrozenDictionary(); + + dict.Clear(); + foreach (var reaction in _prototypeManager.EnumeratePrototypes()) + { + foreach (var reagent in reaction.Reactants.Keys) + { + var list = dict.GetOrNew(reagent); + list.Add(reaction); + } + } + _reactions = dict.ToFrozenDictionary(); + } + + private void OnPaper(PaperInputTextMessageLigyb args) + { + EntityUid? paper = null; + bool printeds = false; + List wasProto = new List(); + foreach (var reactant in args.ReagentQuantity) + { + if (_prototypeManager.TryIndex(reactant.Reagent.Prototype, out ReagentPrototype? protoss)) + { + if (protoss.Group != "Infect") + { + if (paper != null) + { + EntityManager.DeleteEntity(paper); + return; + } + } + } + + if (wasProto.Contains(reactant.Reagent.Prototype)) { continue; } else { wasProto.Add(reactant.Reagent.Prototype); } + if (_reactions.TryGetValue(reactant.Reagent.Prototype, out var reactantReactions)) + { + if (printeds) continue; + else printeds = true; + var printed = EntityManager.SpawnEntity("ForensicReportPaper", Transform(GetEntity(args.Uid)).Coordinates); + paper = printed; + _metaData.SetEntityName(printed, "Технология изготовления вакцины"); + var text = new StringBuilder(); + text.AppendLine("Для изготовления вакцины, требуется:"); + text.AppendLine(); + foreach (var r in reactantReactions) + { + foreach (var reactan in r.Reactants) + { + if (r.MixingCategories == null) + { + _prototypeManager.TryIndex(reactan.Key, out ReagentPrototype? proto); + string no = ""; + text.AppendLine($"{proto?.LocalizedName ?? no}: {reactan.Value.Amount}u"); + } + } + } + text.AppendLine("После чего положить полученную жидкость в вакцинатор, добавив одну каплю крови здорового человека."); + if(TryComp(printed, out var paperComp)) + { + _paperSystem.SetContent((printed, paperComp), text.ToString()); + } + } + } + } + + private void OnPowerChanged(Entity ent, ref PowerChangedEvent args) + { + if (!args.Powered) + StopMix(ent); + } + + protected override bool HasPower(Entity entity) + { + return this.IsPowered(entity, EntityManager); + } +} diff --git a/Content.Shared/_Sunrise/Disease/DiseaseImmuneClothingComponent.cs b/Content.Shared/_Sunrise/Disease/DiseaseImmuneClothingComponent.cs new file mode 100644 index 00000000000..c2018ac9cf9 --- /dev/null +++ b/Content.Shared/_Sunrise/Disease/DiseaseImmuneClothingComponent.cs @@ -0,0 +1,9 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +namespace Content.Shared._Sunrise.Disease; + +[RegisterComponent] +public sealed partial class DiseaseImmuneClothingComponent : Component +{ + [DataField] public float Prob; + [DataField] public bool IsActive; +} diff --git a/Content.Shared/_Sunrise/Disease/DiseaseImmuneComponent.cs b/Content.Shared/_Sunrise/Disease/DiseaseImmuneComponent.cs new file mode 100644 index 00000000000..a15cc3053e6 --- /dev/null +++ b/Content.Shared/_Sunrise/Disease/DiseaseImmuneComponent.cs @@ -0,0 +1,8 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +namespace Content.Shared._Sunrise.Disease; + +[RegisterComponent] +public sealed partial class DiseaseImmuneComponent : Component +{ + +} diff --git a/Content.Shared/_Sunrise/Disease/DiseaseRoleComponent.cs b/Content.Shared/_Sunrise/Disease/DiseaseRoleComponent.cs new file mode 100644 index 00000000000..81a567e310e --- /dev/null +++ b/Content.Shared/_Sunrise/Disease/DiseaseRoleComponent.cs @@ -0,0 +1,40 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Content.Shared.Store; +using Content.Shared.Chemistry.Reagent; +namespace Content.Shared._Sunrise.Disease; + +[RegisterComponent] +public sealed partial class DiseaseRoleComponent : Component +{ + [DataField("actions", customTypeSerializer: typeof(PrototypeIdDictionarySerializer))] + [ViewVariables(VVAccess.ReadWrite)] + public Dictionary Actions = new(); + + [DataField("infected")] + public List Infected = new(); + + [DataField] public EntityUid? Action; + + [DataField] public Dictionary Symptoms = new(); + + [DataField] public int FreeInfects = 3; + [DataField] public int InfectCost = 10; + + [DataField("currencyPrototype", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string CurrencyPrototype = "DiseasePoints"; + + + [DataField] public float BaseInfectChance = 0.6f; + [DataField] public float CoughInfectChance = 0.2f; + + [DataField] public int Lethal = 0; + [DataField] public int Shield = 1; + + [DataField] public int SickOfAllTime = 0; + + [DataField("newBloodReagent", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string NewBloodReagent = "ZombieBlood"; +} diff --git a/Content.Shared/_Sunrise/Disease/DiseaseTempImmuneComponent.cs b/Content.Shared/_Sunrise/Disease/DiseaseTempImmuneComponent.cs new file mode 100644 index 00000000000..0e5ae794bbf --- /dev/null +++ b/Content.Shared/_Sunrise/Disease/DiseaseTempImmuneComponent.cs @@ -0,0 +1,8 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +namespace Content.Shared._Sunrise.Disease; + +[RegisterComponent] +public sealed partial class DiseaseTempImmuneComponent : Component +{ + [DataField] public float Prob = 0; +} diff --git a/Content.Shared/_Sunrise/Disease/DiseaseVaccineTimerComponent.cs b/Content.Shared/_Sunrise/Disease/DiseaseVaccineTimerComponent.cs new file mode 100644 index 00000000000..26ede18b02c --- /dev/null +++ b/Content.Shared/_Sunrise/Disease/DiseaseVaccineTimerComponent.cs @@ -0,0 +1,14 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +namespace Content.Shared._Sunrise.Disease; + +[RegisterComponent] +public sealed partial class DiseaseVaccineTimerComponent : Component +{ + [ViewVariables(VVAccess.ReadOnly)] + public TimeSpan ReadyAt = TimeSpan.Zero; + + [DataField] public TimeSpan Delay = TimeSpan.FromMinutes(5); + + [DataField] public float SpeedBefore = 0; + [DataField] public bool Immune; +} diff --git a/Content.Shared/_Sunrise/Disease/DiseaseVaccineTimerSystem.cs b/Content.Shared/_Sunrise/Disease/DiseaseVaccineTimerSystem.cs new file mode 100644 index 00000000000..0eceeb571d8 --- /dev/null +++ b/Content.Shared/_Sunrise/Disease/DiseaseVaccineTimerSystem.cs @@ -0,0 +1,62 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +namespace Content.Shared._Sunrise.Disease; +using Robust.Shared.Timing; +using Content.Shared.Movement.Components; +using Content.Shared.Movement.Systems; + +public sealed class DiseaseVaccineTimerSystem : SharedSickSystem +{ + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnShut); + SubscribeLocalEvent(OnInit); + } + public void OnInit(EntityUid uid, DiseaseVaccineTimerComponent component, ComponentInit args) + { + component.ReadyAt = _gameTiming.CurTime + component.Delay; + if (TryComp(uid, out var speed)) + { + component.SpeedBefore = speed.BaseSprintSpeed; + _movementSpeed.ChangeBaseSpeed(uid, speed.BaseWalkSpeed, speed.BaseSprintSpeed / 2, speed.Acceleration, speed); + } + } + public void OnShut(EntityUid uid, DiseaseVaccineTimerComponent component, ComponentShutdown args) + { + if (component.SpeedBefore != 0) + { + if (TryComp(uid, out var speed)) + { + _movementSpeed.ChangeBaseSpeed(uid, speed.BaseWalkSpeed, component.SpeedBefore, speed.Acceleration, speed); + } + } + + } + public override void Update(float frameTime) + { + base.Update(frameTime); + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var component)) + { + if (_gameTiming.CurTime >= component.ReadyAt) + { + if (!HasComp(uid)) + { + RemComp(uid); + return; + } + + RemComp(uid); + + if (component.Immune) + { + EnsureComp(uid); + } + RemComp(uid); + } + } + } + +} diff --git a/Content.Shared/_Sunrise/Disease/InfectEvent.cs b/Content.Shared/_Sunrise/Disease/InfectEvent.cs new file mode 100644 index 00000000000..33558368b37 --- /dev/null +++ b/Content.Shared/_Sunrise/Disease/InfectEvent.cs @@ -0,0 +1,96 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Shared.Actions; +using Robust.Shared.Serialization; +using Content.Shared.Inventory; +namespace Content.Shared._Sunrise.Disease; + +public sealed partial class InfectEvent : EntityTargetActionEvent +{ +} + +[Serializable, NetSerializable] +public sealed class InfectWithChanceEvent : EntityEventArgs, IInventoryRelayEvent +{ + // Whenever locational damage is a thing, this should just check only that bit of armour. + public bool Handled = false; + public SlotFlags TargetSlots { get; } = ~SlotFlags.POCKET; + + public readonly NetEntity Target; + public readonly NetEntity Disease; + public float Prob; + + public InfectWithChanceEvent(NetEntity target, NetEntity disease, float prob) + { + Prob = prob; + Target = target; + Disease = disease; + } +} + +[Serializable, NetSerializable] +public sealed partial class ClientInfectEvent : EntityEventArgs +{ + public NetEntity Infected { get; } + public NetEntity Owner { get; } + public ClientInfectEvent(NetEntity infected, NetEntity owner) + { + Infected = infected; + Owner = owner; + } +} + +public sealed partial class DiseaseShopActionEvent : InstantActionEvent +{ +} + + +[Serializable, NetSerializable] +public sealed partial class DiseaseBuyEvent : EntityEventArgs +{ + public readonly string BuyId; + + public DiseaseBuyEvent(string buyId = "Sus") + { + BuyId = buyId; + } +} + + +public sealed partial class DiseaseAddSymptomEvent : InstantActionEvent +{ + [DataField] public string Symptom; + [DataField] public int MinLevel = 0; + [DataField] public int MaxLevel = 9999; +} + + +public sealed partial class DiseaseAddBaseChanceEvent : InstantActionEvent +{ +} + +public sealed partial class DiseaseAddCoughChanceEvent : InstantActionEvent +{ +} + +public sealed partial class DiseaseAddLethalEvent : InstantActionEvent +{ +} + +public sealed partial class DiseaseAddShieldEvent : InstantActionEvent +{ +} + +[Serializable, NetSerializable] +public sealed class UpdateInfectionsEvent : EntityEventArgs +{ + public NetEntity Uid { get; } + public UpdateInfectionsEvent(NetEntity id) + { + Uid = id; + } +} + + + + + diff --git a/Content.Shared/_Sunrise/Disease/SharedDiseaseRoleSystem.cs b/Content.Shared/_Sunrise/Disease/SharedDiseaseRoleSystem.cs new file mode 100644 index 00000000000..17402fd18a8 --- /dev/null +++ b/Content.Shared/_Sunrise/Disease/SharedDiseaseRoleSystem.cs @@ -0,0 +1,37 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Robust.Shared.Random; +using Content.Shared.Humanoid; + +namespace Content.Shared._Sunrise.Disease; + +public abstract class SharedDiseaseRoleSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _robustRandom = default!; + public override void Initialize() + { + base.Initialize(); + } + public void OnInfect(InfectEvent ev, float probability = 0) + { + if (ev.Handled) + return; + ev.Handled = true; + + if (!TryComp(ev.Performer, out var comp)) return; + if (!HasComp(ev.Target)) return; + if (HasComp(ev.Target)) return; + if (HasComp(ev.Target)) return; + + var prob = probability; + if (probability == 0) prob = comp.BaseInfectChance; + if (TryComp(ev.Target, out var immune)) + prob -= immune.Prob; + prob = Math.Max(Math.Min(prob, 0), 1); + if (_robustRandom.Prob(prob)) + { + var comps = AddComp(ev.Target); + comps.owner = ev.Performer; + comp.Infected.Add(ev.Target); + } + } +} diff --git a/Content.Shared/_Sunrise/Disease/SharedSickSystem.cs b/Content.Shared/_Sunrise/Disease/SharedSickSystem.cs new file mode 100644 index 00000000000..8d8d6a70f3d --- /dev/null +++ b/Content.Shared/_Sunrise/Disease/SharedSickSystem.cs @@ -0,0 +1,45 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Shared.CCVar; +using Content.Shared.Mind.Components; +using Content.Shared.Mobs.Systems; +using Content.Shared.NPC; +using Content.Shared.SSDIndicator; +using Content.Shared.StatusIcon; +using Content.Shared.StatusIcon.Components; +using Robust.Shared.Configuration; +using Robust.Shared.Prototypes; +using Content.Shared._Sunrise.Disease; +namespace Content.Shared._Sunrise.Disease; +using Content.Shared.Drunk; +using Content.Shared.StatusEffect; +using Robust.Shared.Enums; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; +using Content.Shared._Sunrise.Disease; +using Robust.Shared.Random; +public abstract class SharedSickSystem : EntitySystem +{ + + [Dependency] private readonly IRobustRandom _robustRandom = default!; + public override void Initialize() + { + base.Initialize(); + } + + public void OnInfected(EntityUid uid, EntityUid disease, float prob) + { + if (HasComp(uid)) return; + + + if (_robustRandom.Prob(prob)) + { + EnsureComp(uid).owner = disease; + if (TryComp(disease, out var compd)) + { + compd.Infected.Add(uid); + } + RaiseNetworkEvent(new UpdateInfectionsEvent(GetNetEntity(uid))); + } + + } +} diff --git a/Content.Shared/_Sunrise/Disease/SharedVaccinatorSystem.cs b/Content.Shared/_Sunrise/Disease/SharedVaccinatorSystem.cs new file mode 100644 index 00000000000..4c662f1d227 --- /dev/null +++ b/Content.Shared/_Sunrise/Disease/SharedVaccinatorSystem.cs @@ -0,0 +1,202 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Shared.Chemistry.Components; +using Content.Shared.Chemistry.Reaction; +using Content.Shared.Interaction; +using Content.Shared.Popups; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Containers; +using Robust.Shared.Network; +using Robust.Shared.Timing; +using System.Collections.Frozen; +using Content.Shared.Paper; +using Robust.Shared.Utility; +using static Content.Shared.Paper.PaperComponent; +using Robust.Shared.Prototypes; +using System.Linq; +using Robust.Shared.Serialization; +using Content.Shared.Chemistry.Reagent; +namespace Content.Shared.Chemistry.EntitySystems; + +/// +/// This handles +/// +public abstract class SharedVaccinatorSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly INetManager _net = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedContainerSystem _container = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly SharedSolutionContainerSystem _solution = default!; + [Dependency] private readonly MetaDataSystem _metaData = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly IGameTiming _gameTiming = default!; + /// + /// A cache of all reactions indexed by at most ONE of their required reactants. + /// I.e., even if a reaction has more than one reagent, it will only ever appear once in this dictionary. + /// + private FrozenDictionary> _reactionsSingle = default!; + + /// + /// A cache of all reactions indexed by one of their required reactants. + /// + private FrozenDictionary> _reactions = default!; + + /// + public override void Initialize() + { + InitializeReactionCache(); + SubscribeLocalEvent(OnActivateInWorld); + SubscribeLocalEvent(OnRemoveAttempt); + } + + + /// + /// Handles building the reaction cache. + /// + private void InitializeReactionCache() + { + // Construct single-reaction dictionary. + var dict = new Dictionary>(); + foreach (var reaction in _prototypeManager.EnumeratePrototypes()) + { + // For this dictionary we only need to cache based on the first reagent. + var reagent = reaction.Reactants.Keys.First(); + var list = dict.GetOrNew(reagent); + list.Add(reaction); + } + _reactionsSingle = dict.ToFrozenDictionary(); + + dict.Clear(); + foreach (var reaction in _prototypeManager.EnumeratePrototypes()) + { + foreach (var reagent in reaction.Reactants.Keys) + { + var list = dict.GetOrNew(reagent); + list.Add(reaction); + } + } + _reactions = dict.ToFrozenDictionary(); + } + + private void OnActivateInWorld(Entity entity, ref ActivateInWorldEvent args) + { + TryStartMix(entity, args.User); + } + + private void OnRemoveAttempt(Entity ent, ref ContainerIsRemovingAttemptEvent args) + { + if (args.Container.ID == ent.Comp.ContainerId && ent.Comp.Mixing) + args.Cancel(); + } + + protected virtual bool HasPower(Entity entity) + { + return true; + } + + public void TryStartMix(Entity entity, EntityUid? user) + { + var (uid, comp) = entity; + if (comp.Mixing) + return; + + if (!HasPower(entity)) + { + if (user != null) + _popup.PopupClient(Loc.GetString("solution-container-mixer-no-power"), entity, user.Value); + return; + } + + if (!_container.TryGetContainer(uid, comp.ContainerId, out var container) || container.Count == 0) + { + if (user != null) + _popup.PopupClient(Loc.GetString("solution-container-mixer-popup-nothing-to-mix"), entity, user.Value); + return; + } + + comp.Mixing = true; + try + { + if (_net.IsServer) + comp.MixingSoundEntity = _audio.PlayPvs(comp.MixingSound, entity, comp.MixingSound?.Params.WithLoop(true)); + } + catch { } + comp.MixTimeEnd = _timing.CurTime + comp.MixDuration; + _appearance.SetData(entity, SolutionContainerMixerVisuals.Mixing, true); + Dirty(uid, comp); + } + + public void StopMix(Entity entity) + { + var (uid, comp) = entity; + if (!comp.Mixing) + return; + _audio.Stop(comp.MixingSoundEntity); + _appearance.SetData(entity, SolutionContainerMixerVisuals.Mixing, false); + comp.Mixing = false; + comp.MixingSoundEntity = null; + Dirty(uid, comp); + } + + public void FinishMix(Entity entity) + { + var (uid, comp) = entity; + if (!comp.Mixing) + return; + StopMix(entity); + + if (!TryComp(entity, out var reactionMixer) + || !_container.TryGetContainer(uid, comp.ContainerId, out var container)) + return; + bool printed = false; + foreach (var ent in container.ContainedEntities) + { + if (!_solution.TryGetFitsInDispenser(ent, out var soln, out _)) + continue; + if (!printed) + { + if (!(_gameTiming.CurTime < comp.PrintReadyAt)) + { + RaiseNetworkEvent(new PaperInputTextMessageLigyb(soln.Value.Comp.Solution.Contents, GetNetEntity(uid))); + printed = true; + comp.PrintReadyAt = _gameTiming.CurTime + comp.PrintCooldown; + } + } + _solution.UpdateChemicals(soln.Value, true, reactionMixer); + + } + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var comp)) + { + if (!comp.Mixing) + continue; + + if (_timing.CurTime < comp.MixTimeEnd) + continue; + + FinishMix((uid, comp)); + } + } +} + + + +[Serializable, NetSerializable] +public sealed class PaperInputTextMessageLigyb : EntityEventArgs +{ + public readonly List ReagentQuantity; + public readonly NetEntity Uid; + public PaperInputTextMessageLigyb(List reagentQuantity, NetEntity uid) + { + Uid = uid; + ReagentQuantity = reagentQuantity; + } +} diff --git a/Content.Shared/_Sunrise/Disease/SickComponent.cs b/Content.Shared/_Sunrise/Disease/SickComponent.cs new file mode 100644 index 00000000000..5b9e78d8003 --- /dev/null +++ b/Content.Shared/_Sunrise/Disease/SickComponent.cs @@ -0,0 +1,34 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Shared.StatusIcon; +using Robust.Shared.GameStates; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Shared._Sunrise.Disease; + +[RegisterComponent] +public sealed partial class SickComponent : Component +{ + [DataField("owner")] + [ViewVariables(VVAccess.ReadWrite)] + public EntityUid owner; + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("icon", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string Icon = "SickIcon"; + + [DataField("inited")] + public bool Inited = false; + + [DataField] public int Stady = 0; + + [DataField] public List Symptoms = new(); + + [ViewVariables(VVAccess.ReadOnly)] + public TimeSpan NextStadyAt = TimeSpan.Zero; + + [DataField("stadyDelay")] + public TimeSpan StadyDelay = TimeSpan.FromMinutes(5); + + [DataField("beforeInfectedBloodReagent")] + public string BeforeInfectedBloodReagent = string.Empty; +} diff --git a/Content.Shared/_Sunrise/Disease/SpeedModifierOnComponent.cs b/Content.Shared/_Sunrise/Disease/SpeedModifierOnComponent.cs new file mode 100644 index 00000000000..12f15f9f676 --- /dev/null +++ b/Content.Shared/_Sunrise/Disease/SpeedModifierOnComponent.cs @@ -0,0 +1,33 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Shared.Clothing; +using Robust.Shared.GameStates; + +namespace Content.Shared.Item; + +/// +/// This is used for items that change your speed when they are held. +/// +/// +/// This is separate from because things like boots increase/decrease speed when worn, but +/// shouldn't do that when just held in hand. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(SpeedModifierOnSystem))] +public sealed partial class SpeedModifierOnComponent : Component +{ + /// + /// A multiplier applied to the walk speed. + /// + [DataField] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public float WalkModifier = 0.6f; + + /// + /// A multiplier applied to the sprint speed. + /// + [DataField] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public float SprintModifier = 0.6f; + + [DataField] public bool TurnedOff; +} diff --git a/Content.Shared/_Sunrise/Disease/SpeedModifierOnSystem.cs b/Content.Shared/_Sunrise/Disease/SpeedModifierOnSystem.cs new file mode 100644 index 00000000000..32186fc4992 --- /dev/null +++ b/Content.Shared/_Sunrise/Disease/SpeedModifierOnSystem.cs @@ -0,0 +1,41 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Shared.Clothing; +using Content.Shared.Hands; +using Content.Shared.Movement.Systems; + +namespace Content.Shared.Item; + +/// +/// This handles +/// +public sealed class SpeedModifierOnSystem : EntitySystem +{ + [Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!; + + /// + public override void Initialize() + { + SubscribeLocalEvent(OnGotEquippedHand); + SubscribeLocalEvent(OnGotUnequippedHand); + SubscribeLocalEvent(OnRefreshMovementSpeedModifiers); + } + + private void OnGotEquippedHand(EntityUid uid, SpeedModifierOnComponent component, ComponentInit args) + { + _movementSpeedModifier.RefreshMovementSpeedModifiers(uid); + } + + private void OnGotUnequippedHand(EntityUid uid, SpeedModifierOnComponent component, ComponentShutdown args) + { + component.TurnedOff = true; + _movementSpeedModifier.RefreshMovementSpeedModifiers(uid); + } + + private void OnRefreshMovementSpeedModifiers(EntityUid uid, SpeedModifierOnComponent component, RefreshMovementSpeedModifiersEvent args) + { + if (!component.TurnedOff) + { + args.ModifySpeed(component.WalkModifier, component.SprintModifier); + } + } +} diff --git a/Content.Shared/_Sunrise/Disease/VaccinatorComponent.cs b/Content.Shared/_Sunrise/Disease/VaccinatorComponent.cs new file mode 100644 index 00000000000..0751864ce4c --- /dev/null +++ b/Content.Shared/_Sunrise/Disease/VaccinatorComponent.cs @@ -0,0 +1,64 @@ +// © SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt +using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.Chemistry.Reaction; +using Robust.Shared.Audio; +using Robust.Shared.Audio.Components; +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Prototypes; +namespace Content.Shared.Chemistry.Components; + +/// +/// This is used for an entity that uses to mix any container with a solution after a period of time. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(SharedVaccinatorSystem))] +public sealed partial class VaccinatorComponent : Component +{ + [DataField, ViewVariables(VVAccess.ReadWrite)] + public string ContainerId = "mixer"; + + [DataField, AutoNetworkedField] + public bool Mixing; + + /// + /// How long it takes for mixing to occurs. + /// + [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public TimeSpan MixDuration; + + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public TimeSpan MixTimeEnd; + + [DataField, AutoNetworkedField] + public SoundSpecifier? MixingSound; + + [DataField] + public Entity? MixingSoundEntity; + + /// + /// The sound that's played when the scanner prints off a report. + /// + [DataField("soundPrint")] + public SoundSpecifier SoundPrint = new SoundPathSpecifier("/Audio/Machines/short_print_and_rip.ogg"); + + /// + /// What the machine will print + /// + [DataField("machineOutput", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string MachineOutput = "ForensicReportPaper"; + + /// + /// When will the scanner be ready to print again? + /// + [ViewVariables(VVAccess.ReadOnly)] + public TimeSpan PrintReadyAt = TimeSpan.Zero; + + /// + /// How often can the scanner print out reports? + /// + [DataField("printCooldown")] + public TimeSpan PrintCooldown = TimeSpan.FromSeconds(5); +} diff --git a/Resources/Locale/ru-RU/_sunrise/disease/disease.ftl b/Resources/Locale/ru-RU/_sunrise/disease/disease.ftl new file mode 100644 index 00000000000..50fc06422d9 --- /dev/null +++ b/Resources/Locale/ru-RU/_sunrise/disease/disease.ftl @@ -0,0 +1,13 @@ +mob-name-disease = Разумная болезнь +mob-description-disease = plague inc 2.0 +ghostrole-disease-name = разумная болезнь +ghostrole-disease-description = Обычная болезнь, которая вдруг решила стать разумной. С кем не бывает? +action-disease-infect-name = Заразить [10 ОЭ] +action-disease-infect-description = Попытка заразить существо [-10 очков эволюции]. Первые три попытки заражения не требуют очков эволюции. Выберите способность и нажмите ЛКМ по сущности, чтобы заразить. +action-disease-shop-name = Мутация +action-disease-shop-description = Открывает меню мутации + +disease-round-end-result = [color=green]На станции была разумная болезнь. Ей было:[/color] +disease-round-end-result-infected = Заражено: [color=gold]{ $count }[/color] +disease-round-end-result-infects = Заражённых в конце раунда: [color=gold]{ $count }[/color] +disease-round-end-result-immuned = Иммунитет был у [color=gold]{ $count }[/color] чел. diff --git a/Resources/Locale/ru-RU/_sunrise/disease/shop.ftl b/Resources/Locale/ru-RU/_sunrise/disease/shop.ftl new file mode 100644 index 00000000000..46aaef24326 --- /dev/null +++ b/Resources/Locale/ru-RU/_sunrise/disease/shop.ftl @@ -0,0 +1,34 @@ +shop-disease-category-infect = Передача +shop-disease-category-symptoms = Симптомы +shop-disease-category-evolution = Улучшение +shop-disease-currency = Очки эволюции +listing-disease-cough-name = Кашель +listing-disease-cough-description = Заражённые начинают кашлять. +listing-disease-sneeze-name = Чих +listing-disease-sneeze-description = Заражённые начинают чихать. +listing-disease-vomit-name = Тошнота +listing-disease-vomit-description = Заражённых начинает тоншить, вызывая рвоту. +listing-disease-zombie-name = Зомбирование +listing-disease-zombie-description = 70% текущих заражённых становятся зомби. Они так-же перестают быть заражёнными. +listing-disease-cry-name = Непроизвольные слёзы +listing-disease-cry-description = У заражённых активно слезятся глаза, из-за чего кажется, что они плачут. +listing-disease-base-chance-name = Улучшение заражения. [20 ОЭ] +listing-disease-base-chance-description = Действие 'заразить' имеет больший шанс на успех. [-20 очков эволюции] +listing-disease-infect-chance-name = Повышение заразности. [15 ОЭ] +listing-disease-infect-chance-description = Увеличивает заразность вируса. Влияет на шанс заражения. [-15 очков эволюции] +listing-disease-shield-name = Повышение устойчивости. [15 ОЭ] +listing-disease-shield-description = Повышает устойчивость болезни к лекарствам. Влияет на скорость лечения при употреблении лекарства. [-15 очков эволюции] +listing-disease-lethal-name = Повышение летальности. [15 ОЭ] +listing-disease-lethal-description = Увеличивает получаемый урон от симптомов. Влияет на получаемый при кашле урон. [-15 очков эволюции] +listing-disease-narcolepsy-name = Сонливость +listing-disease-narcolepsy-description = У заражённых появляется постоянное желание спать, с которым они иногда не могут справиться. +listing-disease-muted-name = Немота +listing-disease-muted-description = Мутация вызывает повреждение подъязычного нерва, приводя к параличу мышц языка, из-за чего больные теряют возможность нормально говорить. +listing-disease-slowness-name = Изнеможение +listing-disease-slowness-description = Вирус вызывает разрушение мышечных волокон, приводящее к атрофие и сопровождающееся слабостью. Снижает общую мобильность +listing-disease-bleed-name = Кровопотеря +listing-disease-bleed-description = Вирус вызывает денатурацию гемоглобина крови, из-за чего у всех носителей появляется тяжелая степень анемии +listing-disease-blindness-name = Слепота +listing-disease-blindness-description = Длительная болезнь приводит к отмиранию зрительного нерва, что приводит к практически полной слепоте больного. +listing-disease-insult-name = Судороги +listing-disease-insult-description = Длительная болезнь вызывает гиперстимуляцию двигательных нейронов, в результате чего больные могут испытывать перенапряжение мышц, приводящие к судорогам. diff --git a/Resources/Locale/ru-RU/_sunrise/disease/vaccine.ftl b/Resources/Locale/ru-RU/_sunrise/disease/vaccine.ftl new file mode 100644 index 00000000000..36a9a17e288 --- /dev/null +++ b/Resources/Locale/ru-RU/_sunrise/disease/vaccine.ftl @@ -0,0 +1,14 @@ +reagent-name-disease-blood = мутная кровь +reagent-description-disease-bad-physical-desc = мерзкое +reagent-description-disease-strange-physical-desc = странное +mixing-verb-vaccinator = вакцинатор +reagent-description-disease-blood = очень странная жидкость. Напоминает кровь +reagent-name-disease-blood-reagent = заражённая жидкость +reagent-name-notready-vaccine = вирусин +reagent-description-notready-vaccine = эта мерзкая жидкость не то, что не вылечит вас, она ещё и заразит. Очень опасно. +reagent-name-vaccine = антивирусин +reagent-description-vaccine = с лёгкостью сможет освободить вас от оков вируса! Не связывается с иммунитетом. +reagent-name-vaccine-plus = антивирусин Плюс +reagent-description-vaccine-plus = наделит вас иммунитетом перед вирусом! + + diff --git a/Resources/Prototypes/Chemistry/mixing_types.yml b/Resources/Prototypes/Chemistry/mixing_types.yml index fd732564108..b9e661fca43 100644 --- a/Resources/Prototypes/Chemistry/mixing_types.yml +++ b/Resources/Prototypes/Chemistry/mixing_types.yml @@ -38,6 +38,13 @@ sprite: Structures/Machines/Medical/centrifuge.rsi state: base +- type: mixingCategory + id: Vaccinator + verbText: mixing-verb-vaccinator + icon: + sprite: Structures/Machines/vaccinator.rsi + state: icon + - type: mixingCategory id: Electrolysis verbText: mixing-verb-electrolysis diff --git a/Resources/Prototypes/Entities/Clothing/Hands/gloves.yml b/Resources/Prototypes/Entities/Clothing/Hands/gloves.yml index 515e13d9752..e616485449a 100644 --- a/Resources/Prototypes/Entities/Clothing/Hands/gloves.yml +++ b/Resources/Prototypes/Entities/Clothing/Hands/gloves.yml @@ -6,6 +6,8 @@ components: - type: Sprite sprite: Clothing/Hands/Gloves/Boxing/boxingred.rsi + - type: DiseaseImmuneClothing + prob: 0.2 - type: Clothing sprite: Clothing/Hands/Gloves/Boxing/boxingred.rsi - type: StaminaDamageOnHit @@ -151,6 +153,8 @@ components: - type: Sprite sprite: Clothing/Hands/Gloves/nitrile.rsi + - type: DiseaseImmuneClothing + prob: 0.4 - type: Clothing sprite: Clothing/Hands/Gloves/nitrile.rsi - type: Fiber diff --git a/Resources/Prototypes/Entities/Clothing/Head/hoods.yml b/Resources/Prototypes/Entities/Clothing/Head/hoods.yml index c9e19cb31b2..f21e557de41 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hoods.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hoods.yml @@ -7,6 +7,8 @@ components: - type: Sprite sprite: Clothing/Head/Hoods/Bio/general.rsi + - type: DiseaseImmuneClothing + prob: 0.3 - type: Clothing sprite: Clothing/Head/Hoods/Bio/general.rsi - type: BreathMask diff --git a/Resources/Prototypes/Entities/Clothing/Masks/masks.yml b/Resources/Prototypes/Entities/Clothing/Masks/masks.yml index 25f9f28d093..542d5212431 100644 --- a/Resources/Prototypes/Entities/Clothing/Masks/masks.yml +++ b/Resources/Prototypes/Entities/Clothing/Masks/masks.yml @@ -4,6 +4,8 @@ name: gas mask description: A face-covering mask that can be connected to an air supply. components: + - type: DiseaseImmuneClothing + prob: 0.35 - type: Sprite sprite: Clothing/Mask/gas.rsi - type: Clothing @@ -292,6 +294,8 @@ components: - type: Sprite sprite: Clothing/Mask/sterile.rsi + - type: DiseaseImmuneClothing + prob: 0.4 - type: Clothing sprite: Clothing/Mask/sterile.rsi - type: IngestionBlocker diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/bio.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/bio.yml index fec4d4df6c7..e0d2b01df46 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/bio.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/bio.yml @@ -7,6 +7,8 @@ components: - type: Sprite sprite: Clothing/OuterClothing/Bio/general.rsi + - type: DiseaseImmuneClothing + prob: 0.8 - type: Clothing sprite: Clothing/OuterClothing/Bio/general.rsi - type: Armor diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml index 1bfa77d7734..837509d3880 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml @@ -10,6 +10,8 @@ components: - type: Sprite sprite: Clothing/OuterClothing/Hardsuits/basic.rsi + - type: DiseaseImmuneClothing + prob: 0.25 - type: Clothing sprite: Clothing/OuterClothing/Hardsuits/basic.rsi - type: ExplosionResistance diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml index 53542cdfa91..b699bb2fb9b 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml @@ -18,6 +18,21 @@ - type: DiseaseMachineVisuals idleState: icon runningState: running + - type: Vaccinator + mixDuration: 10 + mixingSound: + path: /Audio/Machines/spinning.ogg + params: + volume: -4 + - type: ReactionMixer + reactionTypes: + - Vaccinator + - type: ItemSlots + slots: + mixer: + whitelist: + tags: + - CentrifugeCompatible - type: Machine board: VaccinatorMachineCircuitboard - type: ContainerContainer diff --git a/Resources/Prototypes/_Sunrise/Disease/Actions.yml b/Resources/Prototypes/_Sunrise/Disease/Actions.yml new file mode 100644 index 00000000000..1c8904ad963 --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Disease/Actions.yml @@ -0,0 +1,82 @@ +- type: entity + id: ActionInfect + name: action-disease-infect-name + description: action-disease-infect-description + noSpawn: true + components: + - type: EntityTargetAction + useDelay: 1 + itemIconStyle: BigAction + whitelist: + components: + - HumanoidAppearance + canTargetSelf: false + interactOnMiss: false + icon: + sprite: Ligyb/disease.rsi + state: action + event: !type:InfectEvent + +- type: entity + id: ActionDiseaseShop + name: action-disease-shop-name + description: action-disease-shop-description + noSpawn: true + components: + - type: InstantAction + icon: + sprite: Ligyb/disease.rsi + state: shop + event: !type:DiseaseShopActionEvent + +- type: entity + id: ActionDiseaseBaseChance + name: listing-disease-base-chance-name + description: listing-disease-base-chance-description + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Ligyb/disease.rsi + state: baseChance + event: !type:DiseaseAddBaseChanceEvent + +- type: entity + id: ActionDiseaseInfectChance + name: listing-disease-infect-chance-name + description: listing-disease-infect-chance-description + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Ligyb/disease.rsi + state: coughChance + event: !type:DiseaseAddCoughChanceEvent + +- type: entity + id: ActionDiseaseShield + name: listing-disease-shield-name + description: listing-disease-shield-description + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Ligyb/disease.rsi + state: shield + event: !type:DiseaseAddShieldEvent + +- type: entity + id: ActionDiseaseLethal + name: listing-disease-lethal-name + description: listing-disease-lethal-description + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Ligyb/disease.rsi + state: lethal + event: !type:DiseaseAddLethalEvent diff --git a/Resources/Prototypes/_Sunrise/Disease/DiseaseRole.yml b/Resources/Prototypes/_Sunrise/Disease/DiseaseRole.yml new file mode 100644 index 00000000000..491965bdbf1 --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Disease/DiseaseRole.yml @@ -0,0 +1,95 @@ +- type: entity + id: MobDisease + name: разумная болезнь + description: plague inc 2.0 + components: + - type: MindContainer + - type: InputMover + - type: MobMover + - type: Input + context: "ghost" + - type: MovementSpeedModifier + baseWalkSpeed: 6 + baseSprintSpeed: 6 + - type: Sprite + noRot: true + drawdepth: Ghosts + sprite: Ligyb/disease.rsi + layers: + - state: idle + - type: Clickable + - type: InteractionOutline + - type: Physics + bodyType: KinematicController + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.40 + density: 80 + mask: + - GhostImpassable + - type: MovementIgnoreGravity + - type: Damageable + damageContainer: Biological + - type: Examiner + - type: NoSlip + - type: Actions + - type: Eye + drawFov: false + visMask: + - Normal + - Ghost + - type: ContentEye + maxZoom: 1.2, 1.2 + - type: DoAfter + - type: Alerts + - type: GhostRole + makeSentient: true + name: ghostrole-disease-name + description: ghostrole-disease-description + requirements: + - !type:DepartmentTimeRequirement + department: Medical + time: 7200 #2 hrs + - !type:OverallPlaytimeRequirement + time: 18000 #5 hrs + raffle: + settings: default + + - type: GhostTakeoverAvailable + - type: PointLight + color: "#52964F" + radius: 2 + softness: 1 + - type: UserInterface + interfaces: + enum.StoreUiKey.Key: + type: StoreBoundUserInterface + - type: Visibility + layer: 2 #ghost vis layer + - type: Store + categories: + - DiseaseInfectCategory + - DiseaseSymptomsCategory + - DiseaseEvolutionCategory + currencyWhitelist: + - DiseasePoints + balance: + DiseasePoints: 20 + - type: DiseaseRole + actions: + ActionInfect: -1 + ActionDiseaseBaseChance: -1 + ActionDiseaseInfectChance: -1 + ActionDiseaseShield: -1 + ActionDiseaseLethal: -1 + +- type: statusIcon + id: SickIcon + icon: + sprite: /Textures/Ligyb/disease.rsi + state: sick + priority: 2 + diff --git a/Resources/Prototypes/_Sunrise/Disease/Emotes/AutoEmotes.yml b/Resources/Prototypes/_Sunrise/Disease/Emotes/AutoEmotes.yml new file mode 100644 index 00000000000..4c23aeb185b --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Disease/Emotes/AutoEmotes.yml @@ -0,0 +1,41 @@ +- type: autoEmote + id: InfectedCough + emote: Cough + interval: 8.0 + chance: 0.15 + withChat: true + +- type: autoEmote + id: InfectedSneeze + emote: Sneeze + interval: 13.0 + chance: 0.1 + withChat: true + +- type: autoEmote + id: InfectedVomit + emote: Vomit + interval: 23.0 + chance: 0.1 + withChat: false + +- type: autoEmote + id: InfectedCrying + emote: Crying + interval: 12 + chance: 0.08 + withChat: true + +- type: autoEmote + id: InfectedHeadache + emote: Headache + interval: 12 + chance: 0.5 + withChat: false + +- type: autoEmote + id: InfectedInsult + emote: Insult + interval: 16 + chance: 0.3 + withChat: false \ No newline at end of file diff --git a/Resources/Prototypes/_Sunrise/Disease/Emotes/Emotes.yml b/Resources/Prototypes/_Sunrise/Disease/Emotes/Emotes.yml new file mode 100644 index 00000000000..408cc8158bf --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Disease/Emotes/Emotes.yml @@ -0,0 +1,17 @@ +- type: emote + id: Vomit + name: Тошнота + category: Vocal + chatMessages: [тошнитыы] + +- type: emote + id: Headache + name: Головная боль + category: Vocal + chatMessages: [голова болитыы] + +- type: emote + id: Insult + name: Инсульт + category: Vocal + chatMessages: [инсультыы] diff --git a/Resources/Prototypes/_Sunrise/Disease/Store/Actions.yml b/Resources/Prototypes/_Sunrise/Disease/Store/Actions.yml new file mode 100644 index 00000000000..3743f6787d6 --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Disease/Store/Actions.yml @@ -0,0 +1,150 @@ +- type: entity + id: ActionDiseaseCough + name: listing-disease-cough-name + description: listing-disease-cough-description + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Ligyb/disease.rsi + state: cough + event: !type:DiseaseAddSymptomEvent + symptom: "Cough" + minLevel: 2 + +- type: entity + id: ActionDiseaseSneeze + name: listing-disease-sneeze-name + description: listing-disease-sneeze-description + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Ligyb/disease.rsi + state: sneeze + event: !type:DiseaseAddSymptomEvent + symptom: "Sneeze" + minLevel: 3 + +- type: entity + id: ActionDiseaseVomit + name: listing-disease-vomit-name + description: listing-disease-vomit-description + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Ligyb/disease.rsi + state: vomit + event: !type:DiseaseAddSymptomEvent + symptom: "Vomit" + minLevel: 3 + +- type: entity + id: ActionDiseaseNarcolepsy + name: listing-disease-narcolepsy-name + description: listing-disease-narcolepsy-description + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Ligyb/disease.rsi + state: narcolepsy + event: !type:DiseaseAddSymptomEvent + symptom: "Narcolepsy" + minLevel: 3 + +- type: entity + id: ActionDiseaseCrying + name: listing-disease-cry-name + description: listing-disease-cry-description + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Ligyb/disease.rsi + state: sob + event: !type:DiseaseAddSymptomEvent + symptom: "Crying" + minLevel: 0 + +- type: entity + id: ActionDiseaseMuted + name: listing-disease-muted-name + description: listing-disease-muted-description + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Ligyb/disease.rsi + state: muted + event: !type:DiseaseAddSymptomEvent + symptom: "Muted" + minLevel: 4 + +- type: entity + id: ActionDiseaseSlowness + name: listing-disease-slowness-name + description: listing-disease-slowness-description + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Ligyb/disease.rsi + state: slowness + event: !type:DiseaseAddSymptomEvent + symptom: "Slowness" + minLevel: 2 + +- type: entity + id: ActionDiseaseBleed + name: listing-disease-bleed-name + description: listing-disease-bleed-description + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Ligyb/disease.rsi + state: bleed + event: !type:DiseaseAddSymptomEvent + symptom: "Bleed" + minLevel: 3 + +- type: entity + id: ActionDiseaseBlindness + name: listing-disease-blindness-name + description: listing-disease-blindness-description + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Ligyb/disease.rsi + state: blindness + event: !type:DiseaseAddSymptomEvent + symptom: "Blindness" + minLevel: 4 + +- type: entity + id: ActionDiseaseInsult + name: listing-disease-insult-name + description: listing-disease-insult-description + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + icon: + sprite: Ligyb/disease.rsi + state: lethal + event: !type:DiseaseAddSymptomEvent + symptom: "Insult" + minLevel: 2 + diff --git a/Resources/Prototypes/_Sunrise/Disease/Store/Categories.yml b/Resources/Prototypes/_Sunrise/Disease/Store/Categories.yml new file mode 100644 index 00000000000..fe99baa5a3d --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Disease/Store/Categories.yml @@ -0,0 +1,17 @@ +- type: storeCategory + id: DiseaseInfectCategory + name: shop-disease-category-infect + +- type: storeCategory + id: DiseaseSymptomsCategory + name: shop-disease-category-symptoms + +- type: storeCategory + id: DiseaseEvolutionCategory + name: shop-disease-category-evolution + + +- type: currency + id: DiseasePoints + displayName: shop-disease-currency + canWithdraw: false \ No newline at end of file diff --git a/Resources/Prototypes/_Sunrise/Disease/Store/Listings.yml b/Resources/Prototypes/_Sunrise/Disease/Store/Listings.yml new file mode 100644 index 00000000000..ea58b11658f --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Disease/Store/Listings.yml @@ -0,0 +1,140 @@ +- type: listing + id: Cough + name: listing-disease-cough-name + description: listing-disease-cough-description + icon: { sprite: /Textures/Ligyb/disease.rsi, state: cough } + raiseProductEventOnUser: true + productAction: ActionDiseaseCough + cost: + DiseasePoints: 0 + categories: + - DiseaseInfectCategory + conditions: + - !type:ListingLimitedStockCondition + stock: 1 + +- type: listing + id: Sneeze + name: listing-disease-sneeze-name + description: listing-disease-sneeze-description + icon: { sprite: /Textures/Ligyb/disease.rsi, state: sneeze } + productAction: ActionDiseaseSneeze + cost: + DiseasePoints: 20 + categories: + - DiseaseInfectCategory + conditions: + - !type:ListingLimitedStockCondition + stock: 1 + +- type: listing + id: Vomit + name: listing-disease-vomit-name + description: listing-disease-vomit-description + icon: { sprite: /Textures/Ligyb/disease.rsi, state: vomit } + productAction: ActionDiseaseVomit + cost: + DiseasePoints: 25 + categories: + - DiseaseSymptomsCategory + conditions: + - !type:ListingLimitedStockCondition + stock: 1 + +- type: listing + id: Narcolepsy + name: listing-disease-narcolepsy-name + description: listing-disease-narcolepsy-description + icon: { sprite: /Textures/Ligyb/disease.rsi, state: narcolepsy } + productAction: ActionDiseaseNarcolepsy + cost: + DiseasePoints: 20 + categories: + - DiseaseSymptomsCategory + conditions: + - !type:ListingLimitedStockCondition + stock: 1 + +- type: listing + id: Crying + name: listing-disease-cry-name + description: listing-disease-cry-description + icon: { sprite: /Textures/Ligyb/disease.rsi, state: sob } + productAction: ActionDiseaseCrying + cost: + DiseasePoints: 10 + categories: + - DiseaseSymptomsCategory + conditions: + - !type:ListingLimitedStockCondition + stock: 1 + +- type: listing + id: Muted + name: listing-disease-muted-name + description: listing-disease-muted-description + icon: { sprite: /Textures/Ligyb/disease.rsi, state: muted } + productAction: ActionDiseaseMuted + cost: + DiseasePoints: 25 + categories: + - DiseaseSymptomsCategory + conditions: + - !type:ListingLimitedStockCondition + stock: 1 + +- type: listing + id: Slowness + name: listing-disease-slowness-name + description: listing-disease-slowness-description + icon: { sprite: /Textures/Ligyb/disease.rsi, state: slowness } + productAction: ActionDiseaseSlowness + cost: + DiseasePoints: 15 + categories: + - DiseaseSymptomsCategory + conditions: + - !type:ListingLimitedStockCondition + stock: 1 + +- type: listing + id: Bleed + name: listing-disease-bleed-name + description: listing-disease-bleed-description + icon: { sprite: /Textures/Ligyb/disease.rsi, state: bleed } + productAction: ActionDiseaseBleed + cost: + DiseasePoints: 30 + categories: + - DiseaseSymptomsCategory + conditions: + - !type:ListingLimitedStockCondition + stock: 1 + +- type: listing + id: Blindness + name: listing-disease-blindness-name + description: listing-disease-blindness-description + icon: { sprite: /Textures/Ligyb/disease.rsi, state: blindness } + productAction: ActionDiseaseBlindness + cost: + DiseasePoints: 40 + categories: + - DiseaseSymptomsCategory + conditions: + - !type:ListingLimitedStockCondition + stock: 1 + +- type: listing + id: Insult + name: listing-disease-insult-name + description: listing-disease-insult-description + icon: { sprite: /Textures/Ligyb/disease.rsi, state: lethal } + productAction: ActionDiseaseInsult + cost: + DiseasePoints: 20 + categories: + - DiseaseSymptomsCategory + conditions: + - !type:ListingLimitedStockCondition + stock: 1 diff --git a/Resources/Prototypes/_Sunrise/Disease/events.yml b/Resources/Prototypes/_Sunrise/Disease/events.yml new file mode 100644 index 00000000000..b33170a839d --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Disease/events.yml @@ -0,0 +1,15 @@ +- type: entity + parent: BaseGameRule + id: DiseaseSpawn + categories: [ HideSpawnMenu ] + components: + - type: StationEvent + minimumPlayers: 40 + weight: 10 + maxOccurrences: 1 + duration: 1 + earliestStart: 30 + reoccurrenceDelay: 20 + - type: LateJoinSpawnRule + prototype: MobDisease + diff --git a/Resources/Prototypes/_Sunrise/Disease/roundstart.yml b/Resources/Prototypes/_Sunrise/Disease/roundstart.yml new file mode 100644 index 00000000000..d707fc5504e --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Disease/roundstart.yml @@ -0,0 +1,6 @@ +- type: entity + id: DiseaseRule + parent: BaseGameRule + categories: [ HideSpawnMenu ] + components: + - type: DiseaseRule diff --git a/Resources/Prototypes/_Sunrise/Vaccine/Reactions/BloodToVaccine.yml b/Resources/Prototypes/_Sunrise/Vaccine/Reactions/BloodToVaccine.yml new file mode 100644 index 00000000000..3f94b890d65 --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Vaccine/Reactions/BloodToVaccine.yml @@ -0,0 +1,38 @@ +- type: reaction + id: NotReadyVaccineFirst + reactants: + Dylovene: + amount: 2 + Ammonia: + amount: 3 + DiseaseBloodFirst: + amount: 15 + products: + Blood: 15 + NotReadyVaccine: 5 + +- type: reaction + id: NotReadyVaccineSecond + reactants: + Dylovene: + amount: 2 + Leporazine: + amount: 6 + DiseaseBloodSecond: + amount: 15 + products: + Blood: 15 + NotReadyVaccine: 8 + +- type: reaction + id: NotReadyVaccineThird + reactants: + Lipozine: + amount: 3 + Leporazine: + amount: 3 + DiseaseBloodThird: + amount: 15 + products: + Blood: 15 + NotReadyVaccine: 6 \ No newline at end of file diff --git a/Resources/Prototypes/_Sunrise/Vaccine/Reactions/Centrifuge.yml b/Resources/Prototypes/_Sunrise/Vaccine/Reactions/Centrifuge.yml new file mode 100644 index 00000000000..544e594dc56 --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Vaccine/Reactions/Centrifuge.yml @@ -0,0 +1,35 @@ +- type: reaction + id: DiseaseBloodBreakdownFirst + source: true + requiredMixerCategories: + - Centrifuge + reactants: + DiseaseBloodFirst: + amount: 15 + products: + Water: 6 + DiseaseBloodReagent: 9 + +- type: reaction + id: DiseaseBloodBreakdownSecond + source: true + requiredMixerCategories: + - Centrifuge + reactants: + DiseaseBloodSecond: + amount: 15 + products: + Water: 6 + DiseaseBloodReagent: 9 + +- type: reaction + id: DiseaseBloodBreakdownThird + source: true + requiredMixerCategories: + - Centrifuge + reactants: + DiseaseBloodThird: + amount: 15 + products: + Water: 6 + DiseaseBloodReagent: 9 \ No newline at end of file diff --git a/Resources/Prototypes/_Sunrise/Vaccine/Reactions/VaccinatorInspect.yml b/Resources/Prototypes/_Sunrise/Vaccine/Reactions/VaccinatorInspect.yml new file mode 100644 index 00000000000..090de108cbf --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Vaccine/Reactions/VaccinatorInspect.yml @@ -0,0 +1,33 @@ +- type: reaction + id: VaccineInspectFirst + source: true + requiredMixerCategories: + - Vaccinator + reactants: + DiseaseBloodFirst: + amount: 20 + products: + DiseaseBloodFirst: 1 + +- type: reaction + id: VaccineInspectSecond + source: true + requiredMixerCategories: + - Vaccinator + reactants: + DiseaseBloodSecond: + amount: 20 + products: + DiseaseBloodSecond: 1 + +- type: reaction + id: VaccineInspectThird + source: true + requiredMixerCategories: + - Vaccinator + reactants: + DiseaseBloodThird: + amount: 20 + products: + DiseaseBloodThird: 1 + diff --git a/Resources/Prototypes/_Sunrise/Vaccine/Reactions/VaccineCreate.yml b/Resources/Prototypes/_Sunrise/Vaccine/Reactions/VaccineCreate.yml new file mode 100644 index 00000000000..ddc913274eb --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Vaccine/Reactions/VaccineCreate.yml @@ -0,0 +1,27 @@ +- type: reaction + id: VaccineCreate + source: true + requiredMixerCategories: + - Vaccinator + reactants: + NotReadyVaccine: + amount: 19 + Blood: + amount: 1 + products: + Vaccine: 20 + +- type: reaction + id: VaccinePlusCreate + reactants: + Cryptobiolin: + amount: 5 + Sigynate: + amount: 5 + Vaccine: + amount: 7 + DiseaseBloodReagent: + amount: 11 + products: + VaccinePlus: 15 + Water: 10 diff --git a/Resources/Prototypes/_Sunrise/Vaccine/Reagents/blood.yml b/Resources/Prototypes/_Sunrise/Vaccine/Reagents/blood.yml new file mode 100644 index 00000000000..94b4afc29a6 --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Vaccine/Reagents/blood.yml @@ -0,0 +1,95 @@ +- type: reagent + id: DiseaseBloodFirst + name: reagent-name-disease-blood + group: Infect + desc: reagent-description-disease-blood + physicalDesc: reagent-description-disease-bad-physical-desc + flavor: bitter + color: "#722222" + slippery: false + metabolisms: + Drink: + # Disgusting! + effects: + - !type:SatiateThirst + factor: -0.5 + Poison: + effects: + - !type:HealthChange + damage: + types: + Poison: 4 + - !type:ChemVomit + probability: 0.25 + +- type: reagent + id: DiseaseBloodSecond + name: reagent-name-disease-blood + group: Infect + desc: reagent-description-disease-blood + physicalDesc: reagent-description-disease-bad-physical-desc + flavor: bitter + color: "#733333" + slippery: false + metabolisms: + Drink: + # Disgusting! + effects: + - !type:SatiateThirst + factor: -0.5 + Poison: + effects: + - !type:HealthChange + damage: + types: + Poison: 4 + - !type:ChemVomit + probability: 0.25 + +- type: reagent + id: DiseaseBloodThird + name: reagent-name-disease-blood + group: Infect + desc: reagent-description-disease-blood + physicalDesc: reagent-description-disease-bad-physical-desc + flavor: bitter + color: "#815131" + slippery: false + metabolisms: + Drink: + # Disgusting! + effects: + - !type:SatiateThirst + factor: -0.5 + Poison: + effects: + - !type:HealthChange + damage: + types: + Poison: 4 + - !type:ChemVomit + probability: 0.88 + +- type: reagent + id: DiseaseBloodReagent + name: reagent-name-disease-blood-reagent + group: Biological + desc: reagent-description-disease-blood + physicalDesc: reagent-description-disease-bad-physical-desc + flavor: bitter + color: "#737373" + slippery: false + metabolisms: + Drink: + # Disgusting! + effects: + - !type:SatiateThirst + factor: -0.5 + Poison: + effects: + - !type:HealthChange + damage: + types: + Poison: 8 + - !type:ChemVomit + probability: 1 diff --git a/Resources/Prototypes/_Sunrise/Vaccine/Reagents/vaccine.yml b/Resources/Prototypes/_Sunrise/Vaccine/Reagents/vaccine.yml new file mode 100644 index 00000000000..b1b7c4a14fd --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Vaccine/Reagents/vaccine.yml @@ -0,0 +1,41 @@ +- type: reagent + id: NotReadyVaccine + name: reagent-name-notready-vaccine + group: Medicine + desc: reagent-description-notready-vaccine + physicalDesc: reagent-description-disease-strange-physical-desc + flavor: medicine + color: "#83a7b1" + +- type: reagent + id: Vaccine + name: reagent-name-vaccine + group: Medicine + desc: reagent-description-vaccine + physicalDesc: reagent-description-disease-strange-physical-desc + flavor: medicine + color: "#86caf7" + metabolisms: + Medicine: + effects: + - !type:CureDiseaseInfection + conditions: + - !type:ReagentThreshold + min: 10 + +- type: reagent + id: VaccinePlus + name: reagent-name-vaccine-plus + group: Medicine + desc: reagent-description-vaccine-plus + physicalDesc: reagent-description-disease-strange-physical-desc + flavor: medicine + color: "#8192ea" + metabolisms: + Medicine: + effects: + - !type:CureDiseaseInfection + innoculate: true + conditions: + - !type:ReagentThreshold + min: 7 diff --git a/Resources/Textures/Ligyb/disease.rsi/action.png b/Resources/Textures/Ligyb/disease.rsi/action.png new file mode 100644 index 00000000000..90b2ae8bcab Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/action.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/baseChance.png b/Resources/Textures/Ligyb/disease.rsi/baseChance.png new file mode 100644 index 00000000000..18beae1c39b Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/baseChance.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/bleed.png b/Resources/Textures/Ligyb/disease.rsi/bleed.png new file mode 100644 index 00000000000..4e6e5750614 Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/bleed.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/blindness.png b/Resources/Textures/Ligyb/disease.rsi/blindness.png new file mode 100644 index 00000000000..72248efb6b9 Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/blindness.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/cough.png b/Resources/Textures/Ligyb/disease.rsi/cough.png new file mode 100644 index 00000000000..a98e8fa5a0d Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/cough.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/coughChance.png b/Resources/Textures/Ligyb/disease.rsi/coughChance.png new file mode 100644 index 00000000000..ee5e910ed74 Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/coughChance.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/icon.png b/Resources/Textures/Ligyb/disease.rsi/icon.png new file mode 100644 index 00000000000..197b7e1ab84 Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/icon.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/idle.png b/Resources/Textures/Ligyb/disease.rsi/idle.png new file mode 100644 index 00000000000..ff450f9022b Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/idle.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/lethal.png b/Resources/Textures/Ligyb/disease.rsi/lethal.png new file mode 100644 index 00000000000..c1b35925fc7 Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/lethal.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/meta.json b/Resources/Textures/Ligyb/disease.rsi/meta.json new file mode 100644 index 00000000000..942062b603c --- /dev/null +++ b/Resources/Textures/Ligyb/disease.rsi/meta.json @@ -0,0 +1,68 @@ +{ + "version": 1, + "license": "CC0-1.0", + "copyright": "Made by Ligyb", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "idle" + }, + { + "name": "action" + }, + { + "name": "sick" + }, + { + "name": "shop" + }, + { + "name": "cough" + }, + { + "name": "sneeze" + }, + { + "name": "vomit" + }, + { + "name": "sob" + }, + { + "name": "baseChance" + }, + { + "name": "coughChance" + }, + { + "name": "zombie" + }, + { + "name": "lethal" + }, + { + "name": "shield" + }, + { + "name": "narcolepsy" + }, + { + "name": "muted" + }, + { + "name": "slowness" + }, + { + "name": "bleed" + }, + { + "name": "blindness" + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Ligyb/disease.rsi/muted.png b/Resources/Textures/Ligyb/disease.rsi/muted.png new file mode 100644 index 00000000000..2e5da499243 Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/muted.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/narcolepsy.png b/Resources/Textures/Ligyb/disease.rsi/narcolepsy.png new file mode 100644 index 00000000000..2f935fe39c2 Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/narcolepsy.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/shield.png b/Resources/Textures/Ligyb/disease.rsi/shield.png new file mode 100644 index 00000000000..fc09d787ee3 Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/shield.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/shop.png b/Resources/Textures/Ligyb/disease.rsi/shop.png new file mode 100644 index 00000000000..679b9d946cc Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/shop.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/sick.png b/Resources/Textures/Ligyb/disease.rsi/sick.png new file mode 100644 index 00000000000..8f13560db9d Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/sick.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/slowness.png b/Resources/Textures/Ligyb/disease.rsi/slowness.png new file mode 100644 index 00000000000..4715c22b7b7 Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/slowness.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/sneeze.png b/Resources/Textures/Ligyb/disease.rsi/sneeze.png new file mode 100644 index 00000000000..5005e8d056b Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/sneeze.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/sob.png b/Resources/Textures/Ligyb/disease.rsi/sob.png new file mode 100644 index 00000000000..0ec8b29e31b Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/sob.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/vomit.png b/Resources/Textures/Ligyb/disease.rsi/vomit.png new file mode 100644 index 00000000000..f7cbdc873be Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/vomit.png differ diff --git a/Resources/Textures/Ligyb/disease.rsi/zombie.png b/Resources/Textures/Ligyb/disease.rsi/zombie.png new file mode 100644 index 00000000000..6bf35137dd6 Binary files /dev/null and b/Resources/Textures/Ligyb/disease.rsi/zombie.png differ