fish-station/Content.Server/Ligyb/SickSystem.cs
2024-06-21 05:59:40 +03:00

297 lines
12 KiB
C#

// © 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;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Content.Shared.Ligyb;
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.Audio.Systems;
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.Mobs.Systems;
using Content.Shared.FixedPoint;
using Content.Server.Medical;
using Content.Server.Traits.Assorted;
using Content.Server.Speech.Muting;
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.Ligyb;
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!;
private EntityLookupSystem _lookup => _entityManager.System<EntityLookupSystem>();
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SickComponent, ComponentShutdown>(OnShut);
SubscribeLocalEvent<SickComponent, EmoteEvent>(OnEmote, before:
new[] { typeof(VocalSystem), typeof(BodyEmotesSystem) });
}
public void OnShut(EntityUid uid, SickComponent component, ComponentShutdown args)
{
foreach (var emote in EnsureComp<AutoEmoteComponent>(uid).Emotes)
{
if (emote.Contains("Infected"))
{
_autoEmote.RemoveEmote(uid, emote);
}
}
foreach (var key in component.Symptoms)
{
switch (key)
{
case "Narcolepsy":
if (TryComp<SleepyComponent>(uid, out var narc))
{
RemComp<SleepyComponent>(uid);
}
break;
case "Muted":
if (TryComp<MutedComponent>(uid, out var mute))
{
RemComp<MutedComponent>(uid);
}
break;
case "Blindness":
if (TryComp<PermanentBlindnessComponent>(uid, out var blind))
{
RemComp<PermanentBlindnessComponent>(uid);
}
if (HasComp<BlurryVisionComponent>(uid))
{
RemComp<BlurryVisionComponent>(uid);
}
if (HasComp<EyeClosingComponent>(uid))
{
RemComp<EyeClosingComponent>(uid);
}
break;
case "Slowness":
if (TryComp<SpeedModifierOnComponent>(uid, out var slow))
{
RemComp<SpeedModifierOnComponent>(uid);
}
break;
case "Bleed":
if (TryComp<MinimumBleedComponent>(uid, out var bleed))
{
RemComp<MinimumBleedComponent>(uid);
}
break;
}
}
_bloodstream.ChangeBloodReagent(uid, component.BeforeInfectedBloodReagent);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<SickComponent>();
while (query.MoveNext(out var uid, out var component))
{
if (TryComp<DiseaseRoleComponent>(component.owner, out var diseaseComp))
{
UpdateInfection(uid, component, component.owner, diseaseComp);
if (!component.Inited)
{
//Infect
if (TryComp<BloodstreamComponent>(uid, out var stream))
component.BeforeInfectedBloodReagent = stream.BloodReagent;
_bloodstream.ChangeBloodReagent(uid, diseaseComp.NewBloodReagent);
RaiseNetworkEvent(new ClientInfectEvent(GetNetEntity(uid), GetNetEntity(component.owner)));
AddMoney(uid, 5);
component.Inited = true;
}
else
{
if (_gameTiming.CurTime >= component.NextStadyAt)
{
component.Stady++;
foreach (var emote in EnsureComp<AutoEmoteComponent>(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<SickComponent>(uid, out var component))
{
if (TryComp<DiseaseRoleComponent>(component.owner, out var diseaseComp))
{
if (TryComp<StoreComponent>(component.owner, out var store))
{
bool f = _store.TryAddCurrency(new Dictionary<string, FixedPoint2>
{
{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<AutoEmoteComponent>(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<SleepyComponent>(uid))
{
var c = AddComp<SleepyComponent>(uid);
EntityManager.EntitySysManager.GetEntitySystem<SleepySystem>().SetNarcolepsy(uid, new Vector2(10, 30), new Vector2(300, 600), c);
}
break;
case "Muted":
EnsureComp<MutedComponent>(uid);
break;
case "Blindness":
EnsureComp<PermanentBlindnessComponent>(uid);
break;
case "Slowness":
var ss = EnsureComp<SpeedModifierOnComponent>(uid);
break;
case "Bleed":
EnsureComp<MinimumBleedComponent>(uid);
break;
case "Insult":
_autoEmote.AddEmote(uid, "InfectedInsult");
break;
}
}
}
}
}
private void OnEmote(EntityUid uid, SickComponent component, ref EmoteEvent args)
{
if (args.Handled)
return;
args.Handled = true;
if (args.Emote.ID == "Headache")
{
_popupSystem.PopupEntity("Вы чувствуете лёгкую головную боль.", uid, uid, PopupType.Small);
}
if (args.Emote.ID == "Cough")
{
if (_robustRandom.Prob(0.9f))
{
if (TryComp<DiseaseRoleComponent>(component.owner, out var disease))
{
var kind = SuicideKind.Piercing;
if (_prototypeManager.TryIndex<DamageTypePrototype>(kind.ToString(), out var damagePrototype))
{
_damageableSystem.TryChangeDamage(uid, new(damagePrototype, 0.25f * disease.Lethal), true, origin: uid);
}
}
EntityCoordinates start = Transform(uid).Coordinates;
foreach (var entity in _lookup.GetEntitiesInRange(uid, 0.7f))
{
if (HasComp<HumanoidAppearanceComponent>(entity) && !HasComp<SickComponent>(entity) && !HasComp<DiseaseImmuneComponent>(entity))
{
OnInfected(entity, component.owner, Comp<DiseaseRoleComponent>(component.owner).CoughInfectChance);
}
}
}
}
if (args.Emote.ID == "Sneeze")
{
if (_robustRandom.Prob(0.9f))
{
EntityCoordinates start = Transform(uid).Coordinates;
foreach (var entity in _lookup.GetEntitiesInRange(uid, 1.2f))
{
if (HasComp<HumanoidAppearanceComponent>(entity) && !HasComp<SickComponent>(entity) && !HasComp<DiseaseImmuneComponent>(entity))
{
OnInfected(entity, component.owner, Comp<DiseaseRoleComponent>(component.owner).CoughInfectChance);
}
}
}
}
if (args.Emote.ID == "Vomit")
{
if (_robustRandom.Prob(0.4f))
{
_vomitSystem.Vomit(uid, -30, -20);
}
}
if (args.Emote.ID == "Insult")
{
if (TryComp<DiseaseRoleComponent>(component.owner, out var disease))
{
_stun.TryParalyze(uid, TimeSpan.FromSeconds(5), false);
var kind = SuicideKind.Shock;
if (_prototypeManager.TryIndex<DamageTypePrototype>(kind.ToString(), out var damagePrototype))
{
_damageableSystem.TryChangeDamage(uid, new(damagePrototype, 0.35f * disease.Lethal), true, origin: uid);
}
}
}
}
}