Disease boowomp (#135)

* disease

* eula
This commit is contained in:
Lgibb18 2024-06-21 07:35:09 +05:00 committed by GitHub
parent 7a811c6c39
commit ad39b4f298
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
70 changed files with 2621 additions and 3 deletions

View file

@ -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 Content.Shared.Actions;
using Content.Shared.DoAfter;
using Content.Shared.Doors.Systems;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;
using Robust.Shared.Random;
using Robust.Shared.Serialization.Manager;
using Content.Shared.Humanoid;
using Content.Shared.Ligyb;
namespace Content.Client.Ligyb;
public sealed class DiseaseRoleSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeNetworkEvent<ClientInfectEvent>(OnInfect);
}
private void OnInfect(ClientInfectEvent ev)
{
var target = GetEntity(ev.Infected);
var performer = GetEntity(ev.Owner);
if (!TryComp<HumanoidAppearanceComponent>(target, out var body))
return;
var sick = EnsureComp<SickComponent>(target);
sick.owner = performer;
sick.Inited = true;
if(TryComp<DiseaseRoleComponent>(performer, out var comp))
{
comp.Infected.Add(target);
}
}
}

View file

@ -0,0 +1,51 @@
// © 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.StatusIcon;
using Content.Shared.StatusIcon.Components;
using Robust.Shared.Configuration;
using Robust.Client.Player;
using Robust.Shared.Prototypes;
using Content.Shared.Ligyb;
namespace Content.Client.Ligyb;
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<SickComponent, GetStatusIconsEvent>(OnGetStatusIcon);
SubscribeNetworkEvent<UpdateInfectionsEvent>(OnUpdateInfect);
}
private void OnUpdateInfect(UpdateInfectionsEvent args)
{
EnsureComp<SickComponent>(GetEntity(args.Uid)).Inited = true;
}
private void OnGetStatusIcon(EntityUid uid, SickComponent component, ref GetStatusIconsEvent args)
{
if (component.Inited)
{
if (_playerManager.LocalEntity != null)
{
if (HasComp<DiseaseRoleComponent>(_playerManager.LocalEntity.Value))
{
if (!args.InContainer &&
!_mobState.IsDead(uid) &&
!HasComp<ActiveNPCComponent>(uid) &&
TryComp<MindContainerComponent>(uid, out var mindContainer) &&
mindContainer.ShowExamineInfo)
{
args.StatusIcons.Add(_prototype.Index<StatusIconPrototype>(component.Icon));
}
}
}
}
}
}

View file

@ -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;
/// <inheritdoc/>
public sealed class VaccinatorSystem : SharedVaccinatorSystem
{
}

View file

@ -0,0 +1,35 @@
// © 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.Zombies;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using Content.Shared.Ligyb;
using Content.Server.Spawners.Components;
public sealed partial class CureDiseaseInfection : ReagentEffect
{
[DataField]
public bool Innoculate;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
{
if (Innoculate)
return "ок";
return "окей";
}
public override void Effect(ReagentEffectArgs args)
{
var entityManager = args.EntityManager;
if (!entityManager.HasComponent<SickComponent>(args.SolutionEntity)) return;
if (entityManager.TryGetComponent<SickComponent>(args.SolutionEntity, out var sick))
{
if (entityManager.TryGetComponent<DiseaseRoleComponent>(sick.owner, out var disease))
{
var comp = entityManager.EnsureComponent<DiseaseVaccineTimerComponent>(args.SolutionEntity);
comp.Immune = Innoculate;
comp.delay = TimeSpan.FromMinutes(2) + TimeSpan.FromSeconds(disease.Shield * 30);
}
}
}
}

View file

@ -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.Ligyb;
using Content.Shared.Examine;
using Content.Shared.Verbs;
using Robust.Shared.Utility;
namespace Content.Server.Ligyb;
public sealed class DiseaseImmuneClothingSystem : EntitySystem
{
[Dependency] private readonly ExamineSystemShared _examine = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DiseaseImmuneClothingComponent, GotEquippedEvent>(OnGotEquipped);
SubscribeLocalEvent<DiseaseImmuneClothingComponent, GotUnequippedEvent>(OnGotUnequipped);
SubscribeLocalEvent<DiseaseImmuneClothingComponent, GetVerbsEvent<ExamineVerb>>(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<DiseaseTempImmuneComponent>(args.Equipee).Prob += component.prob;
if (Comp<DiseaseTempImmuneComponent>(args.Equipee).Prob > 1) Comp<DiseaseTempImmuneComponent>(args.Equipee).Prob = 1;
component.IsActive = true;
}
private void OnGotUnequipped(EntityUid uid, DiseaseImmuneClothingComponent component, GotUnequippedEvent args)
{
if (!component.IsActive)
return;
EnsureComp<DiseaseTempImmuneComponent>(args.Equipee).Prob -= component.prob;
if (Comp<DiseaseTempImmuneComponent>(args.Equipee).Prob < 0) Comp<DiseaseTempImmuneComponent>(args.Equipee).Prob = 0;
component.IsActive = false;
}
private void OnArmorVerbExamine(EntityUid uid, DiseaseImmuneClothingComponent component, GetVerbsEvent<ExamineVerb> args)
{
if (!args.CanInteract || !args.CanAccess)
return;
var examineMarkup = new FormattedMessage();
examineMarkup.AddMarkup($"Защищает от заражения на {Convert.ToInt32(component.prob*100)}%");
_examine.AddDetailedExamineVerb(args, component, examineMarkup,
"Стерильность", "/Textures/Interface/VerbIcons/dot.svg.192dpi.png",
"Изучить показатели стерильности.");
}
}

View file

@ -0,0 +1,201 @@
// © 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.Body.Systems;
using Content.Server.Chat.Systems;
using Content.Server.Doors.Systems;
using Content.Server.Weapons.Ranged.Systems;
using Content.Shared.Actions;
using Content.Shared.DoAfter;
using Content.Shared.Doors.Systems;
using Robust.Server.GameObjects;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;
using Robust.Shared.Random;
using Robust.Shared.Serialization.Manager;
using Content.Shared.Ligyb;
using Content.Server.Actions;
using Content.Server.Store.Components;
using Content.Server.Store.Systems;
using Robust.Shared.Prototypes;
using Content.Server.Zombies;
using Content.Shared.FixedPoint;
using Content.Shared.Zombies;
namespace Content.Server.Ligyb;
public sealed class DiseaseRoleSystem : SharedDiseaseRoleSystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
[Dependency] private readonly ActionsSystem _action = default!;
[Dependency] private readonly StoreSystem _store = default!;
[ValidatePrototypeId<EntityPrototype>]
private const string DiseaseShopId = "ActionDiseaseShop";
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DiseaseRoleComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<DiseaseRoleComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseShopActionEvent>(OnShop);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseStartCoughEvent>(OnCough);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseStartSneezeEvent>(OnSneeze);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseStartVomitEvent>(OnVomit);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseStartCryingEvent>(OnCrying);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseZombieEvent>(OnZombie);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseNarcolepsyEvent>(OnNarcolepsy);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseMutedEvent>(OnMuted);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseSlownessEvent>(OnSlowness);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseBleedEvent>(OnBleed);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseBlindnessEvent>(OnBlindness);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseInsultEvent>(OnInsult);
SubscribeLocalEvent<InfectEvent>(OnInfects);
}
private void OnInfects(InfectEvent args)
{
if (TryComp<DiseaseRoleComponent>(args.Performer, out var component))
{
if(component.FreeInfects > 0)
{
component.FreeInfects--;
OnInfect(args);
return;
}
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<string>() { "DiseaseBloodFirst", "DiseaseBloodSecond", "DiseaseBloodThird" });
component.Symptoms.Add("Headache", (1, 4));
}
private void OnMapInit(EntityUid uid, DiseaseRoleComponent component, MapInitEvent args)
{
_action.AddAction(uid, ref component.Action, DiseaseShopId);
}
private void OnShop(EntityUid uid, DiseaseRoleComponent component, DiseaseShopActionEvent args)
{
if (!TryComp<StoreComponent>(uid, out var store))
return;
_store.ToggleUi(uid, uid, store);
}
void AddMoney(EntityUid uid, FixedPoint2 value)
{
if (TryComp<DiseaseRoleComponent>(uid, out var diseaseComp))
{
if (TryComp<StoreComponent>(uid, out var store))
{
bool f = _store.TryAddCurrency(new Dictionary<string, FixedPoint2>
{
{diseaseComp.CurrencyPrototype, value}
}, uid);
_store.UpdateUserInterface(uid, uid, store);
}
}
}
bool TryRemoveMoney(EntityUid uid, FixedPoint2 value)
{
if (TryComp<DiseaseRoleComponent>(uid, out var diseaseComp))
{
if (TryComp<StoreComponent>(uid, out var store))
{
if (store.Balance[diseaseComp.CurrencyPrototype] >= value)
{
bool f = _store.TryAddCurrency(new Dictionary<string, FixedPoint2>
{
{diseaseComp.CurrencyPrototype, -value}
}, uid);
_store.UpdateUserInterface(uid, uid, store);
return true;
} else
{
return false;
}
}
}
return false;
}
private void OnCough(EntityUid uid, DiseaseRoleComponent component, DiseaseStartCoughEvent args)
{
component.Symptoms.Add("Cough", (2, 9999));
}
private void OnSneeze(EntityUid uid, DiseaseRoleComponent component, DiseaseStartSneezeEvent args)
{
//component.Sneeze = true;
component.Symptoms.Add("Sneeze", (3, 9999));
}
private void OnVomit(EntityUid uid, DiseaseRoleComponent component, DiseaseStartVomitEvent args)
{
component.Symptoms.Add("Vomit", (3, 9999));
}
private void OnCrying(EntityUid uid, DiseaseRoleComponent component, DiseaseStartCryingEvent args)
{
component.Symptoms.Add("Crying", (0, 9999));
}
private void OnNarcolepsy(EntityUid uid, DiseaseRoleComponent component, DiseaseNarcolepsyEvent args)
{
component.Symptoms.Add("Narcolepsy", (3, 9999));
}
private void OnMuted(EntityUid uid, DiseaseRoleComponent component, DiseaseMutedEvent args)
{
component.Symptoms.Add("Muted", (4, 9999));
}
private void OnSlowness(EntityUid uid, DiseaseRoleComponent component, DiseaseSlownessEvent args)
{
component.Symptoms.Add("Slowness", (2, 9999));
}
private void OnBleed(EntityUid uid, DiseaseRoleComponent component, DiseaseBleedEvent args)
{
component.Symptoms.Add("Bleed", (3, 9999));
}
private void OnBlindness(EntityUid uid, DiseaseRoleComponent component, DiseaseBlindnessEvent args)
{
component.Symptoms.Add("Blindness", (4, 9999));
}
private void OnInsult(EntityUid uid, DiseaseRoleComponent component, DiseaseInsultEvent args)
{
component.Symptoms.Add("Insult", (2, 9999));
}
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<SickComponent>(infected);
component.Infected.Remove(infected);
EnsureComp<ZombifyOnDeathComponent>(infected);
EnsureComp<PendingZombieComponent>(infected);
}
}
}
}

View file

@ -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.Ligyb;
[RegisterComponent]
public sealed partial class MinimumBleedComponent : Component
{
[DataField] public float MinValue = 1f;
}

View file

@ -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.Ligyb;
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<MinimumBleedComponent>();
while (query.MoveNext(out var uid, out var component))
{
if(TryComp<BloodstreamComponent>(uid, out var blood))
{
if(blood.BleedAmount < component.MinValue)
{
_bloodstream.TryModifyBleedAmount(uid, component.MinValue, blood);
}
}
}
}
}

View file

@ -0,0 +1,295 @@
// © 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;
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);
}
}
}
}
}

View file

@ -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;
}

View file

@ -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<StatusEffectPrototype>]
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<SleepyComponent, ComponentStartup>(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<SleepyComponent>();
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<SleepingComponent>(uid, StatusEffectKey,
TimeSpan.FromSeconds(duration), false);
}
}
}

View file

@ -0,0 +1,146 @@
// © 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.SharedPaperComponent;
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;
/// <inheritdoc/>
public sealed class VaccinatorSystem : SharedVaccinatorSystem
{
/// <inheritdoc/>
///
[Dependency] private readonly PaperSystem _paperSystem = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
/// <summary>
/// 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.
/// </summary>
private FrozenDictionary<string, List<ReactionPrototype>> _reactionsSingle = default!;
/// <summary>
/// A cache of all reactions indexed by one of their required reactants.
/// </summary>
private FrozenDictionary<string, List<ReactionPrototype>> _reactions = default!;
public override void Initialize()
{
base.Initialize();
InitializeReactionCache();
SubscribeLocalEvent<VaccinatorComponent, PowerChangedEvent>(OnPowerChanged);
SubscribeNetworkEvent<PaperInputTextMessageLigyb>(OnPaper);
}
/// <summary>
/// Handles building the reaction cache.
/// </summary>
private void InitializeReactionCache()
{
// Construct single-reaction dictionary.
var dict = new Dictionary<string, List<ReactionPrototype>>();
foreach (var reaction in _prototypeManager.EnumeratePrototypes<ReactionPrototype>())
{
// 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<ReactionPrototype>())
{
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<string> wasProto = new List<string>();
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("После чего положить полученную жидкость в вакцинатор, добавив одну каплю крови здорового человека.");
_paperSystem.SetContent(printed, text.ToString());
}
}
}
private void OnPowerChanged(Entity<VaccinatorComponent> ent, ref PowerChangedEvent args)
{
if (!args.Powered)
StopMix(ent);
}
protected override bool HasPower(Entity<VaccinatorComponent> entity)
{
return this.IsPowered(entity, EntityManager);
}
}

View file

@ -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).
/// </summary>
[DataField("timeBetweenIncidents", required: true)]
public Vector2 TimeBetweenIncidents { get; private set; }
public Vector2 TimeBetweenIncidents = new Vector2(300, 600);
/// <summary>
/// The duration of incidents, (min, max).
/// </summary>
[DataField("durationOfIncident", required: true)]
public Vector2 DurationOfIncident { get; private set; }
public Vector2 DurationOfIncident = new Vector2(10, 30);
public float NextIncidentTime;
}

View file

@ -1,6 +1,7 @@
using Content.Shared.Bed.Sleep;
using Content.Shared.StatusEffect;
using Robust.Shared.Random;
using System.Numerics;
namespace Content.Server.Traits.Assorted;
@ -35,6 +36,14 @@ public sealed class NarcolepsySystem : EntitySystem
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);

View file

@ -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.Ligyb;
[RegisterComponent]
public sealed partial class DiseaseImmuneClothingComponent : Component
{
[DataField] public float prob;
[DataField] public bool IsActive;
}

View file

@ -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.Ligyb;
[RegisterComponent]
public sealed partial class DiseaseImmuneComponent : Component
{
}

View file

@ -0,0 +1,46 @@
// © 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 System.Numerics;
using Content.Shared.FixedPoint;
using Content.Shared.Store;
using Content.Shared.Whitelist;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Content.Shared.Chemistry.Reagent;
namespace Content.Shared.Ligyb;
[RegisterComponent]
public sealed partial class DiseaseRoleComponent : Component
{
[DataField("actions", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<int, EntityPrototype>))]
[ViewVariables(VVAccess.ReadWrite)]
public Dictionary<string, int> Actions = new();
[DataField("infected")]
public List<EntityUid> Infected = new();
[DataField] public EntityUid? Action;
[DataField] public Dictionary<string, (int, int)> Symptoms = new();
[DataField] public int FreeInfects = 3;
[DataField] public int InfectCost = 10;
[DataField("currencyPrototype", customTypeSerializer: typeof(PrototypeIdSerializer<CurrencyPrototype>))]
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;
/// <summary>
/// The blood reagent to give the infected. In case you want infected that bleed milk, or something.
/// </summary>
[DataField("newBloodReagent", customTypeSerializer: typeof(PrototypeIdSerializer<ReagentPrototype>))]
public string NewBloodReagent = "ZombieBlood";
}

View file

@ -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.Ligyb;
[RegisterComponent]
public sealed partial class DiseaseTempImmuneComponent : Component
{
[DataField] public float Prob = 0;
}

View file

@ -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.Ligyb;
[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;
}

View file

@ -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 Robust.Shared.Configuration;
namespace Content.Shared.Ligyb;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;
using Robust.Shared.Random;
using Content.Shared.Mobs.Systems;
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<DiseaseVaccineTimerComponent, ComponentShutdown>(OnShut);
SubscribeLocalEvent<DiseaseVaccineTimerComponent, ComponentInit>(OnInit);
}
public void OnInit(EntityUid uid, DiseaseVaccineTimerComponent component, ComponentInit args)
{
component.ReadyAt = _gameTiming.CurTime + component.delay;
if (TryComp<MovementSpeedModifierComponent>(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<MovementSpeedModifierComponent>(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<DiseaseVaccineTimerComponent>();
while (query.MoveNext(out var uid, out var component))
{
if (_gameTiming.CurTime >= component.ReadyAt)
{
if (!HasComp<SickComponent>(uid))
{
RemComp<DiseaseVaccineTimerComponent>(uid);
return;
}
RemComp<SickComponent>(uid);
if (component.Immune)
{
EnsureComp<DiseaseImmuneComponent>(uid);
}
RemComp<DiseaseVaccineTimerComponent>(uid);
}
}
}
}

View file

@ -0,0 +1,166 @@
// © 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 Content.Shared.Store;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
using System.Linq;
using Content.Shared.Administration.Logs;
using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
using Content.Shared.Inventory;
using Content.Shared.Mind.Components;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Radiation.Events;
using Content.Shared.Rejuvenate;
using Robust.Shared.GameStates;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Shared.Ligyb;
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;
}
}
[Serializable, NetSerializable]
public sealed partial class DiseaseStartCoughEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed partial class DiseaseStartSneezeEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed partial class DiseaseStartVomitEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed partial class DiseaseZombieEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed partial class DiseaseStartCryingEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed partial class DiseaseAddBaseChanceEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed partial class DiseaseAddCoughChanceEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed partial class DiseaseAddLethalEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed partial class DiseaseAddShieldEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed partial class DiseaseNarcolepsyEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed partial class DiseaseMutedEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed partial class DiseaseSlownessEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed partial class DiseaseBleedEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed partial class DiseaseBlindnessEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed partial class DiseaseInsultEvent : EntityEventArgs
{
}
[Serializable, NetSerializable]
public sealed class UpdateInfectionsEvent : EntityEventArgs
{
public NetEntity Uid { get; }
public UpdateInfectionsEvent(NetEntity id)
{
Uid = id;
}
}

View file

@ -0,0 +1,84 @@
// © 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 Content.Shared.DoAfter;
using Content.Shared.Doors.Systems;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;
using Robust.Shared.Random;
using Robust.Shared.Serialization.Manager;
using Content.Shared.Humanoid;
namespace Content.Shared.Ligyb;
public abstract class SharedDiseaseRoleSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _robustRandom = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseAddBaseChanceEvent>(OnBaseChance);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseAddCoughChanceEvent>(OnCoughChance);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseAddLethalEvent>(OnLethal);
SubscribeLocalEvent<DiseaseRoleComponent, DiseaseAddShieldEvent>(OnShield);
}
private void OnLethal(EntityUid uid, DiseaseRoleComponent component, DiseaseAddLethalEvent args)
{
component.Lethal += 1;
}
private void OnShield(EntityUid uid, DiseaseRoleComponent component, DiseaseAddShieldEvent args)
{
component.Shield += 1;
}
private void OnBaseChance(EntityUid uid, DiseaseRoleComponent component, DiseaseAddBaseChanceEvent args)
{
if (component.BaseInfectChance < 0.9f)
component.BaseInfectChance += 0.1f;
else
component.BaseInfectChance = 1;
}
private void OnCoughChance(EntityUid uid, DiseaseRoleComponent component, DiseaseAddCoughChanceEvent args)
{
if (component.CoughInfectChance < 0.85f)
component.CoughInfectChance += 0.05f;
else
component.CoughInfectChance = 1;
}
public void OnInfect(InfectEvent ev)
{
if (ev.Handled)
return;
if (TryComp<DiseaseRoleComponent>(ev.Performer, out var comp))
{
ev.Handled = true;
if (!TryComp<HumanoidAppearanceComponent>(ev.Target, out var body))
return;
if (HasComp<DiseaseImmuneComponent>(ev.Target)) return;
if (HasComp<SickComponent>(ev.Target)) return;
var prob = comp.BaseInfectChance;
if (TryComp<DiseaseTempImmuneComponent>(ev.Target, out var immune))
{
prob -= immune.Prob;
}
if (prob < 0) prob = 0;
if (prob > 1) prob = 1;
if (_robustRandom.Prob(prob))
{
var comps = AddComp<SickComponent>(ev.Target);
comps.owner = ev.Performer;
comp.Infected.Add(ev.Target);
}
}
}
}

View file

@ -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.Ligyb;
namespace Content.Shared.Ligyb;
using Content.Shared.Drunk;
using Content.Shared.StatusEffect;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Content.Shared.Ligyb;
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<DiseaseImmuneComponent>(uid)) return;
if (_robustRandom.Prob(prob))
{
EnsureComp<SickComponent>(uid).owner = disease;
if (TryComp<DiseaseRoleComponent>(disease, out var compd))
{
compd.Infected.Add(uid);
}
RaiseNetworkEvent(new UpdateInfectionsEvent(GetNetEntity(uid)));
}
}
}

View file

@ -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.SharedPaperComponent;
using Robust.Shared.Prototypes;
using System.Linq;
using Robust.Shared.Serialization;
using Content.Shared.Chemistry.Reagent;
namespace Content.Shared.Chemistry.EntitySystems;
/// <summary>
/// This handles <see cref="SolutionContainerMixerComponent"/>
/// </summary>
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!;
/// <summary>
/// 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.
/// </summary>
private FrozenDictionary<string, List<ReactionPrototype>> _reactionsSingle = default!;
/// <summary>
/// A cache of all reactions indexed by one of their required reactants.
/// </summary>
private FrozenDictionary<string, List<ReactionPrototype>> _reactions = default!;
/// <inheritdoc/>
public override void Initialize()
{
InitializeReactionCache();
SubscribeLocalEvent<VaccinatorComponent, ActivateInWorldEvent>(OnActivateInWorld);
SubscribeLocalEvent<VaccinatorComponent, ContainerIsRemovingAttemptEvent>(OnRemoveAttempt);
}
/// <summary>
/// Handles building the reaction cache.
/// </summary>
private void InitializeReactionCache()
{
// Construct single-reaction dictionary.
var dict = new Dictionary<string, List<ReactionPrototype>>();
foreach (var reaction in _prototypeManager.EnumeratePrototypes<ReactionPrototype>())
{
// 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<ReactionPrototype>())
{
foreach (var reagent in reaction.Reactants.Keys)
{
var list = dict.GetOrNew(reagent);
list.Add(reaction);
}
}
_reactions = dict.ToFrozenDictionary();
}
private void OnActivateInWorld(Entity<VaccinatorComponent> entity, ref ActivateInWorldEvent args)
{
TryStartMix(entity, args.User);
}
private void OnRemoveAttempt(Entity<VaccinatorComponent> ent, ref ContainerIsRemovingAttemptEvent args)
{
if (args.Container.ID == ent.Comp.ContainerId && ent.Comp.Mixing)
args.Cancel();
}
protected virtual bool HasPower(Entity<VaccinatorComponent> entity)
{
return true;
}
public void TryStartMix(Entity<VaccinatorComponent> 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<VaccinatorComponent> 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<VaccinatorComponent> entity)
{
var (uid, comp) = entity;
if (!comp.Mixing)
return;
StopMix(entity);
if (!TryComp<ReactionMixerComponent>(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<VaccinatorComponent>();
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> ReagentQuantity;
public readonly NetEntity Uid;
public PaperInputTextMessageLigyb(List<ReagentQuantity> reagentQuantity, NetEntity uid)
{
Uid = uid;
ReagentQuantity = reagentQuantity;
}
}

View file

@ -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.Ligyb;
[RegisterComponent]
public sealed partial class SickComponent : Component
{
[DataField("owner")]
[ViewVariables(VVAccess.ReadWrite)]
public EntityUid owner;
[ViewVariables(VVAccess.ReadWrite)]
[DataField("icon", customTypeSerializer: typeof(PrototypeIdSerializer<StatusIconPrototype>))]
public string Icon = "SickIcon";
[DataField("inited")]
public bool Inited = false;
[DataField] public int Stady = 0;
[DataField] public List<string> 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;
}

View file

@ -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;
/// <summary>
/// This is used for items that change your speed when they are held.
/// </summary>
/// <remarks>
/// This is separate from <see cref="ClothingSpeedModifierComponent"/> because things like boots increase/decrease speed when worn, but
/// shouldn't do that when just held in hand.
/// </remarks>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SpeedModifierOnSystem))]
public sealed partial class SpeedModifierOnComponent : Component
{
/// <summary>
/// A multiplier applied to the walk speed.
/// </summary>
[DataField]
[ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float WalkModifier = 0.6f;
/// <summary>
/// A multiplier applied to the sprint speed.
/// </summary>
[DataField]
[ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float SprintModifier = 0.6f;
[DataField] public bool TurnedOff;
}

View file

@ -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;
/// <summary>
/// This handles <see cref="HeldSpeedModifierComponent"/>
/// </summary>
public sealed class SpeedModifierOnSystem : EntitySystem
{
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!;
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<SpeedModifierOnComponent, ComponentInit>(OnGotEquippedHand);
SubscribeLocalEvent<SpeedModifierOnComponent, ComponentShutdown>(OnGotUnequippedHand);
SubscribeLocalEvent<SpeedModifierOnComponent, RefreshMovementSpeedModifiersEvent>(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);
}
}
}

View file

@ -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;
/// <summary>
/// This is used for an entity that uses <see cref="ReactionMixerComponent"/> to mix any container with a solution after a period of time.
/// </summary>
[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;
/// <summary>
/// How long it takes for mixing to occurs.
/// </summary>
[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<AudioComponent>? MixingSoundEntity;
/// <summary>
/// The sound that's played when the scanner prints off a report.
/// </summary>
[DataField("soundPrint")]
public SoundSpecifier SoundPrint = new SoundPathSpecifier("/Audio/Machines/short_print_and_rip.ogg");
/// <summary>
/// What the machine will print
/// </summary>
[DataField("machineOutput", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string MachineOutput = "ForensicReportPaper";
/// <summary>
/// When will the scanner be ready to print again?
/// </summary>
[ViewVariables(VVAccess.ReadOnly)]
public TimeSpan PrintReadyAt = TimeSpan.Zero;
/// <summary>
/// How often can the scanner print out reports?
/// </summary>
[DataField("printCooldown")]
public TimeSpan PrintCooldown = TimeSpan.FromSeconds(5);
}

View file

@ -0,0 +1,8 @@
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 = Открывает меню мутации

View file

@ -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 = Улучшение заражения.
listing-disease-base-chance-description = Действие 'заразить' имеет больший шанс на успех.
listing-disease-infect-chance-name = Повышение заразности.
listing-disease-infect-chance-description = Увеличивает заразность вируса. Влияет на шанс заражения.
listing-disease-shield-name = Повышение устойчивости.
listing-disease-shield-description = Повышает устойчивость болезни к лекарствам. Влияет на скорость лечения при употреблении лекарства.
listing-disease-lethal-name = Повышение летальности.
listing-disease-lethal-description = Увеличивает получаемый урон от симптомов. Влияет на получаемый при кашле урон.
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 = Длительная болезнь вызывает гиперстимуляцию двигательных нейронов, в результате чего больные могут испытывать перенапряжение мышц, приводящие к судорогам.

View file

@ -0,0 +1,11 @@
reagent-name-disease-blood = мутная кровь
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 = наделит вас иммунитетом перед вирусом!

View file

@ -38,6 +38,13 @@
sprite: Structures/Machines/Medical/centrifuge.rsi
state: base
- type: mixingCategory
id: Vaccinator
verbText: Вакцинатор
icon:
sprite: Structures/Machines/Medical/centrifuge.rsi
state: base
- type: mixingCategory
id: Electrolysis
verbText: mixing-verb-electrolysis

View file

@ -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
@ -153,6 +155,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

View file

@ -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

View file

@ -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
@ -274,6 +276,8 @@
components:
- type: Sprite
sprite: Clothing/Mask/sterile.rsi
- type: DiseaseImmuneClothing
prob: 0.4
- type: Clothing
sprite: Clothing/Mask/sterile.rsi
- type: IngestionBlocker

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,32 @@
- 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
#sound: !type:SoundPathSpecifier
#path: /Audio/Magic/disintegrate.ogg
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

View file

@ -0,0 +1,82 @@
- 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
- type: GhostTakeoverAvailable
- type: PointLight
color: MediumPurple
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
- type: statusIcon
id: SickIcon
icon:
sprite: /Textures/Ligyb/disease.rsi
state: sick
priority: 2

View file

@ -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

View file

@ -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: [инсультыы]

View file

@ -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

View file

@ -0,0 +1,197 @@
- type: listing
id: Cough
name: listing-disease-cough-name
description: listing-disease-cough-description
icon: { sprite: /Textures/Ligyb/disease.rsi, state: cough }
productEvent: !type:DiseaseStartCoughEvent
cost:
DiseasePoints: 15
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 }
productEvent: !type:DiseaseStartSneezeEvent
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 }
productEvent: !type:DiseaseStartVomitEvent
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 }
productEvent: !type:DiseaseNarcolepsyEvent
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 }
productEvent: !type:DiseaseStartCryingEvent
cost:
DiseasePoints: 10
categories:
- DiseaseSymptomsCategory
conditions:
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: BaseChance
name: listing-disease-base-chance-name
description: listing-disease-base-chance-description
icon: { sprite: /Textures/Ligyb/disease.rsi, state: baseChance }
productEvent: !type:DiseaseAddBaseChanceEvent
cost:
DiseasePoints: 20
categories:
- DiseaseEvolutionCategory
conditions:
- !type:ListingLimitedStockCondition
stock: 4
- type: listing
id: CoughChance
name: listing-disease-infect-chance-name
description: listing-disease-infect-chance-description
icon: { sprite: /Textures/Ligyb/disease.rsi, state: coughChance }
productEvent: !type:DiseaseAddBaseChanceEvent
cost:
DiseasePoints: 15
categories:
- DiseaseEvolutionCategory
conditions:
- !type:ListingLimitedStockCondition
stock: 8
- type: listing
id: Shield
name: listing-disease-shield-name
description: listing-disease-shield-description
icon: { sprite: /Textures/Ligyb/disease.rsi, state: shield }
productEvent: !type:DiseaseAddShieldEvent
cost:
DiseasePoints: 15
categories:
- DiseaseEvolutionCategory
conditions:
- !type:ListingLimitedStockCondition
stock: 5
- type: listing
id: Lethal
name: listing-disease-lethal-name
description: listing-disease-lethal-description
icon: { sprite: /Textures/Ligyb/disease.rsi, state: lethal }
productEvent: !type:DiseaseAddLethalEvent
cost:
DiseasePoints: 15
categories:
- DiseaseEvolutionCategory
conditions:
- !type:ListingLimitedStockCondition
stock: 5
- type: listing
id: Muted
name: listing-disease-muted-name
description: listing-disease-muted-description
icon: { sprite: /Textures/Ligyb/disease.rsi, state: muted }
productEvent: !type:DiseaseMutedEvent
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 }
productEvent: !type:DiseaseSlownessEvent
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 }
productEvent: !type:DiseaseBleedEvent
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 }
productEvent: !type:DiseaseBlindnessEvent
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: blindness }
productEvent: !type:DiseaseInsultEvent
cost:
DiseasePoints: 20
categories:
- DiseaseSymptomsCategory
conditions:
- !type:ListingLimitedStockCondition
stock: 1

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,95 @@
- type: reagent
id: DiseaseBloodFirst
name: reagent-name-disease-blood
group: Infect
desc: reagent-description-disease-blood
physicalDesc: мерзкое
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: мерзкое
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: мерзкое
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: мерзкое
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

View file

@ -0,0 +1,41 @@
- type: reagent
id: NotReadyVaccine
name: reagent-name-notready-vaccine
group: Medicine
desc: reagent-description-notready-vaccine
physicalDesc: странное
flavor: medicine
color: "#83a7b1"
- type: reagent
id: Vaccine
name: reagent-name-vaccine
group: Medicine
desc: reagent-description-vaccine
physicalDesc: странное
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: сладкое
flavor: medicine
color: "#8192ea"
metabolisms:
Medicine:
effects:
- !type:CureDiseaseInfection
innoculate: true
conditions:
- !type:ReagentThreshold
min: 7

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

View file

@ -0,0 +1,66 @@
{
"version": 1,
"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"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 B