using Content.Shared.Damage; using Content.Shared.Damage.Prototypes; using Content.Shared.EntityEffects; using Content.Shared.FixedPoint; using Content.Shared.Localizations; using JetBrains.Annotations; using Robust.Shared.Prototypes; using System.Linq; using System.Text.Json.Serialization; using Content.Shared._Shitmed.EntityEffects.Effects; // Shitmed Change using Content.Shared._Shitmed.Targeting; // Shitmed Change using Content.Server.Temperature.Components; // Shitmed Change namespace Content.Server.EntityEffects.Effects { /// /// Default metabolism used for medicine reagents. /// [UsedImplicitly] public sealed partial class HealthChange : EntityEffect { /// /// Damage to apply every cycle. Damage Ignores resistances. /// [DataField(required: true)] [JsonPropertyName("damage")] public DamageSpecifier Damage = default!; /// /// Should this effect scale the damage by the amount of chemical in the solution? /// Useful for touch reactions, like styptic powder or acid. /// Only usable if the EntityEffectBaseArgs is an EntityEffectReagentArgs. /// [DataField] [JsonPropertyName("scaleByQuantity")] public bool ScaleByQuantity; [DataField] [JsonPropertyName("ignoreResistances")] public bool IgnoreResistances = true; protected override string ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) { var damages = new List(); var heals = false; var deals = false; var damageSpec = new DamageSpecifier(Damage); var universalReagentDamageModifier = entSys.GetEntitySystem().UniversalReagentDamageModifier; var universalReagentHealModifier = entSys.GetEntitySystem().UniversalReagentHealModifier; if (universalReagentDamageModifier != 1 || universalReagentHealModifier != 1) { foreach (var (type, val) in damageSpec.DamageDict) { if (val < 0f) { damageSpec.DamageDict[type] = val * universalReagentHealModifier; } if (val > 0f) { damageSpec.DamageDict[type] = val * universalReagentDamageModifier; } } } damageSpec = entSys.GetEntitySystem().ApplyUniversalAllModifiers(damageSpec); foreach (var group in prototype.EnumeratePrototypes()) { if (!damageSpec.TryGetDamageInGroup(group, out var amount)) continue; var relevantTypes = damageSpec.DamageDict .Where(x => x.Value != FixedPoint2.Zero && group.DamageTypes.Contains(x.Key)).ToList(); if (relevantTypes.Count != group.DamageTypes.Count) continue; var sum = FixedPoint2.Zero; foreach (var type in group.DamageTypes) { sum += damageSpec.DamageDict.GetValueOrDefault(type); } // if the total sum of all the types equal the damage amount, // assume that they're evenly distributed. if (sum != amount) continue; var sign = FixedPoint2.Sign(amount); if (sign < 0) heals = true; if (sign > 0) deals = true; damages.Add( Loc.GetString("health-change-display", ("kind", group.LocalizedName), ("amount", MathF.Abs(amount.Float())), ("deltasign", sign) )); foreach (var type in group.DamageTypes) { damageSpec.DamageDict.Remove(type); } } foreach (var (kind, amount) in damageSpec.DamageDict) { var sign = FixedPoint2.Sign(amount); if (sign < 0) heals = true; if (sign > 0) deals = true; damages.Add( Loc.GetString("health-change-display", ("kind", prototype.Index(kind).LocalizedName), ("amount", MathF.Abs(amount.Float())), ("deltasign", sign) )); } var healsordeals = heals ? (deals ? "both" : "heals") : (deals ? "deals" : "none"); return Loc.GetString("reagent-effect-guidebook-health-change", ("chance", Probability), ("changes", ContentLocalizationManager.FormatList(damages)), ("healsordeals", healsordeals)); } public override void Effect(EntityEffectBaseArgs args) { var scale = FixedPoint2.New(1); var damageSpec = new DamageSpecifier(Damage); if (args is EntityEffectReagentArgs reagentArgs) { scale = ScaleByQuantity ? reagentArgs.Quantity * reagentArgs.Scale : reagentArgs.Scale; } var universalReagentDamageModifier = args.EntityManager.System().UniversalReagentDamageModifier; var universalReagentHealModifier = args.EntityManager.System().UniversalReagentHealModifier; if (universalReagentDamageModifier != 1 || universalReagentHealModifier != 1) { foreach (var (type, val) in damageSpec.DamageDict) { if (val < 0f) { damageSpec.DamageDict[type] = val * universalReagentHealModifier; } if (val > 0f) { damageSpec.DamageDict[type] = val * universalReagentDamageModifier; } } } args.EntityManager.System() .TryChangeDamage( args.TargetEntity, damageSpec * scale, IgnoreResistances, interruptsDoAfters: false, // Shitmed Change Start targetPart: TargetBodyPart.All, partMultiplier: 0.5f, canSever: false); // Shitmed Change End } } }