From 729ed026c00a0b688d0ddd4b23bbd0a5d72644ce Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Fri, 15 Nov 2024 01:08:26 -0500 Subject: [PATCH 01/26] meow --- Content.Client/_EE/Cocoon/CocoonSystem.cs | 33 +++ Content.Server/_EE/Cocoon/CocoonerSystem.cs | 202 ++++++++++++++++ .../_EE/Vampire/BloodSuckedComponent.cs | 9 + .../_EE/Vampire/BloodSuckerComponent.cs | 44 ++++ .../_EE/Vampire/BloodSuckerSystem.cs | 202 ++++++++++++++++ .../BloodSuckerGlandInjectorComponent.cs | 23 ++ .../BloodSuckerGlandInjectorSystem.cs | 39 +++ Content.Shared/_EE/Cocoon/CocoonComponent.cs | 14 ++ .../_EE/Cocoon/CocoonDoAfterEvent.cs | 15 ++ .../_EE/Cocoon/CocoonerComponent.cs | 14 ++ .../_EE/Vampiric/BloodSuckDoAfterEvent.cs | 10 + .../Locale/en-US/_EE/abilities/arachne.ftl | 16 ++ .../Locale/en-US/_EE/species/species.ftl | 3 + .../Entities/Objects/Misc/spider_web.yml | 3 + .../_EE/Entities/Mobs/Player/arachne.yml | 29 +++ .../_EE/Entities/Mobs/Species/arachne.yml | 222 ++++++++++++++++++ Resources/Prototypes/_EE/Species/arachne.yml | 59 +++++ .../female_full.png | Bin 0 -> 140 bytes .../female_none.png | Bin 0 -> 112 bytes .../female_top.png | Bin 0 -> 140 bytes .../anytaur_masking_helpers.rsi/full.png | Bin 0 -> 112 bytes .../anytaur_masking_helpers.rsi/male_full.png | Bin 0 -> 112 bytes .../anytaur_masking_helpers.rsi/male_none.png | Bin 0 -> 112 bytes .../anytaur_masking_helpers.rsi/male_top.png | Bin 0 -> 112 bytes .../anytaur_masking_helpers.rsi/meta.json | 59 +++++ .../anytaur_masking_helpers.rsi/none.png | Bin 0 -> 112 bytes .../anytaur_masking_helpers.rsi/top.png | Bin 0 -> 112 bytes .../unisex_full.png | Bin 0 -> 112 bytes .../unisex_none.png | Bin 0 -> 112 bytes .../unisex_top.png | Bin 0 -> 112 bytes .../_EE/Mobs/Species/arachne.rsi/meta.json | 19 ++ .../Mobs/Species/arachne.rsi/spider_body.png | Bin 0 -> 3288 bytes .../Species/arachne.rsi/spider_body_front.png | Bin 0 -> 761 bytes .../_EE/Mobs/Species/eyes.rsi/eyes.png | Bin 0 -> 5553 bytes .../_EE/Mobs/Species/eyes.rsi/meta.json | 15 ++ 35 files changed, 1030 insertions(+) create mode 100644 Content.Client/_EE/Cocoon/CocoonSystem.cs create mode 100644 Content.Server/_EE/Cocoon/CocoonerSystem.cs create mode 100644 Content.Server/_EE/Vampire/BloodSuckedComponent.cs create mode 100644 Content.Server/_EE/Vampire/BloodSuckerComponent.cs create mode 100644 Content.Server/_EE/Vampire/BloodSuckerSystem.cs create mode 100644 Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs create mode 100644 Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs create mode 100644 Content.Shared/_EE/Cocoon/CocoonComponent.cs create mode 100644 Content.Shared/_EE/Cocoon/CocoonDoAfterEvent.cs create mode 100644 Content.Shared/_EE/Cocoon/CocoonerComponent.cs create mode 100644 Content.Shared/_EE/Vampiric/BloodSuckDoAfterEvent.cs create mode 100644 Resources/Locale/en-US/_EE/abilities/arachne.ftl create mode 100644 Resources/Locale/en-US/_EE/species/species.ftl create mode 100644 Resources/Prototypes/_EE/Entities/Mobs/Player/arachne.yml create mode 100644 Resources/Prototypes/_EE/Entities/Mobs/Species/arachne.yml create mode 100644 Resources/Prototypes/_EE/Species/arachne.yml create mode 100644 Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/female_full.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/female_none.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/female_top.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/full.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/male_full.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/male_none.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/male_top.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/meta.json create mode 100644 Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/none.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/top.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_full.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_none.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_top.png create mode 100644 Resources/Textures/_EE/Mobs/Species/arachne.rsi/meta.json create mode 100644 Resources/Textures/_EE/Mobs/Species/arachne.rsi/spider_body.png create mode 100644 Resources/Textures/_EE/Mobs/Species/arachne.rsi/spider_body_front.png create mode 100644 Resources/Textures/_EE/Mobs/Species/eyes.rsi/eyes.png create mode 100644 Resources/Textures/_EE/Mobs/Species/eyes.rsi/meta.json diff --git a/Content.Client/_EE/Cocoon/CocoonSystem.cs b/Content.Client/_EE/Cocoon/CocoonSystem.cs new file mode 100644 index 00000000000..b80ad6dfe15 --- /dev/null +++ b/Content.Client/_EE/Cocoon/CocoonSystem.cs @@ -0,0 +1,33 @@ +using Content.Shared.Cocoon; +using Content.Shared.Humanoid; +using Robust.Client.GameObjects; +using Robust.Shared.Containers; +using System.Numerics; + +namespace Content.Client._EE.Cocoon +{ + public sealed class CocoonSystem : EntitySystem + { + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnCocEntInserted); + } + + private void OnCocEntInserted(EntityUid uid, CocoonComponent component, EntInsertedIntoContainerMessage args) + { + if (!TryComp(uid, out var cocoonSprite)) + return; + + if (TryComp(args.Entity, out var humanoidAppearance)) // If humanoid, use height and width + cocoonSprite.Scale = new Vector2(1,1); + else if (!TryComp(args.Entity, out var entSprite)) + return; + else if (entSprite.BaseRSI != null) // Set scale based on sprite scale + sprite dimensions. Ideally we would somehow get a bounding box from the sprite size not including transparent pixels, but FUCK figuring that out. + cocoonSprite.Scale = entSprite.Scale * (entSprite.BaseRSI.Size / 32); + else if (entSprite.Scale != cocoonSprite.Scale) // if basersi somehow not found (?) just use scale + cocoonSprite.Scale = entSprite.Scale; + } + } +} diff --git a/Content.Server/_EE/Cocoon/CocoonerSystem.cs b/Content.Server/_EE/Cocoon/CocoonerSystem.cs new file mode 100644 index 00000000000..0d64781afee --- /dev/null +++ b/Content.Server/_EE/Cocoon/CocoonerSystem.cs @@ -0,0 +1,202 @@ +using Content.Shared.Cocoon; +using Content.Shared.IdentityManagement; +using Content.Shared.Verbs; +using Content.Shared.DoAfter; +using Content.Shared.Stunnable; +using Content.Shared.Eye.Blinding.Systems; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Damage; +using Content.Shared.Administration.Logs; +using Content.Shared.Database; +using Content.Shared.Humanoid; +using Content.Server.Popups; +using Content.Server.DoAfter; +using Content.Server.Speech.Components; +using Robust.Shared.Containers; +using Content.Shared.Mobs.Components; +using Content.Shared.Destructible; +using Robust.Shared.Random; +using Content.Shared.Nutrition.Components; +using Content.Shared.Storage; +using Robust.Shared.Utility; + +namespace Content.Server.Cocoon +{ + public sealed class CocooningSystem : EntitySystem + { + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly DoAfterSystem _doAfter = default!; + [Dependency] private readonly ItemSlotsSystem _itemSlots = default!; + [Dependency] private readonly BlindableSystem _blindableSystem = default!; + [Dependency] private readonly DamageableSystem _damageableSystem = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly SharedDestructibleSystem _destructibleSystem = default!; + [Dependency] private readonly IRobustRandom _robustRandom = default!; + + private const string BodySlot = "body_slot"; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent>(AddVerbs); + SubscribeLocalEvent(OnCocEntInserted); + SubscribeLocalEvent(OnCocEntRemoved); + SubscribeLocalEvent(OnDamageChanged); + SubscribeLocalEvent(OnCocoonDoAfter); + SubscribeLocalEvent(OnUnCocoonDoAfter); + } + + private void AddVerbs(EntityUid uid, CocoonerComponent component, GetVerbsEvent args) + { + AddCocoonVerb(uid, component, args); + AddUnCocoonVerb(uid, component, args); + } + + private void AddCocoonVerb(EntityUid uid, CocoonerComponent component, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract || !HasComp(args.Target)) + return; + + InnateVerb verb = new() + { + Act = () => + { + StartCocooning(uid, component, args.Target); + }, + Text = Loc.GetString("cocoon"), + Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/Actions/web.png")), + Priority = 2 + }; + args.Verbs.Add(verb); + } + + private void AddUnCocoonVerb(EntityUid uid, CocoonerComponent component, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract || !HasComp(args.Target)) + return; + + InnateVerb verb = new() + { + Act = () => + { + StartUnCocooning(uid, component, args.Target); + }, + Text = Loc.GetString("uncocoon"), + Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/Actions/web.png")), + Priority = 2 + }; + args.Verbs.Add(verb); + } + + private void OnCocEntInserted(EntityUid uid, CocoonComponent component, EntInsertedIntoContainerMessage args) + { + component.Victim = args.Entity; + + if (TryComp(args.Entity, out var currentAccent)) + component.OldAccent = currentAccent.Accent; + + EnsureComp(args.Entity).Accent = "mumble"; + EnsureComp(args.Entity); + + _blindableSystem.UpdateIsBlind(args.Entity); + } + + private void OnCocEntRemoved(EntityUid uid, CocoonComponent component, EntRemovedFromContainerMessage args) + { + if (TryComp(args.Entity, out var replacement)) + if (component.OldAccent is not null) + replacement.Accent = component.OldAccent; + else + RemComp(args.Entity, replacement); + + + RemComp(args.Entity); + _blindableSystem.UpdateIsBlind(args.Entity); + } + + private void OnDamageChanged(EntityUid uid, CocoonComponent component, DamageChangedEvent args) + { + if (!args.DamageIncreased || args.DamageDelta == null || component.Victim == null) + return; + + var damage = args.DamageDelta * component.DamagePassthrough; + _damageableSystem.TryChangeDamage(component.Victim, damage); + } + + private void StartCocooning(EntityUid uid, CocoonerComponent component, EntityUid target) + { + _popupSystem.PopupEntity(Loc.GetString("cocoon-start-third-person", ("target", Identity.Entity(target, EntityManager)), ("spider", Identity.Entity(uid, EntityManager))), uid, + Shared.Popups.PopupType.MediumCaution); + + var delay = component.CocoonDelay; + + if (HasComp(target)) + delay *= component.CocoonKnockdownMultiplier; + + var args = new DoAfterArgs(EntityManager, uid, delay, new CocoonDoAfterEvent(), uid, target: target) + { + BreakOnMove = true, + }; + + _doAfter.TryStartDoAfter(args); + } + + private void StartUnCocooning(EntityUid uid, CocoonerComponent component, EntityUid target) + { + _popupSystem.PopupEntity(Loc.GetString("uncocoon-start-third-person", ("target", target), ("spider", Identity.Entity(uid, EntityManager))), uid, + Shared.Popups.PopupType.MediumCaution); + + var delay = component.CocoonDelay / 2; + + var args = new DoAfterArgs(EntityManager, uid, delay, new UnCocoonDoAfterEvent(), uid, target: target) + { + BreakOnMove = true, + }; + + _doAfter.TryStartDoAfter(args); + } + + private void OnCocoonDoAfter(EntityUid uid, CocoonerComponent component, CocoonDoAfterEvent args) + { + if (args.Handled || args.Cancelled || args.Args.Target == null) + return; + + var spawnProto = HasComp(args.Args.Target) ? "CocoonedHumanoid" : "CocoonSmall"; + Transform(args.Args.Target.Value).AttachToGridOrMap(); + var cocoon = Spawn(spawnProto, Transform(args.Args.Target.Value).Coordinates); + + if (!TryComp(cocoon, out var slots)) + return; + + _itemSlots.SetLock(cocoon, BodySlot, false, slots); + _itemSlots.TryInsert(cocoon, BodySlot, args.Args.Target.Value, args.Args.User); + _itemSlots.SetLock(cocoon, BodySlot, true, slots); + + var impact = (spawnProto == "CocoonedHumanoid") ? LogImpact.High : LogImpact.Medium; + + _adminLogger.Add(LogType.Action, impact, $"{ToPrettyString(args.Args.User):player} cocooned {ToPrettyString(args.Args.Target.Value):target}"); + args.Handled = true; + } + + private void OnUnCocoonDoAfter(EntityUid uid, CocoonerComponent component, UnCocoonDoAfterEvent args) + { + if (args.Handled || args.Cancelled || args.Args.Target == null) + return; + + if (TryComp(args.Args.Target.Value, out var butcher)) + { + var spawnEntities = EntitySpawnCollection.GetSpawns(butcher.SpawnedEntities, _robustRandom); + var coords = Transform(args.Args.Target.Value).MapPosition; + EntityUid popupEnt = default!; + foreach (var proto in spawnEntities) + popupEnt = Spawn(proto, coords.Offset(_robustRandom.NextVector2(0.25f))); + } + + _destructibleSystem.DestroyEntity(args.Args.Target.Value); + + _adminLogger.Add(LogType.Action, LogImpact.Low + , $"{ToPrettyString(args.Args.User):player} uncocooned {ToPrettyString(args.Args.Target.Value):target}"); + args.Handled = true; + } + } +} diff --git a/Content.Server/_EE/Vampire/BloodSuckedComponent.cs b/Content.Server/_EE/Vampire/BloodSuckedComponent.cs new file mode 100644 index 00000000000..d7e402cd98a --- /dev/null +++ b/Content.Server/_EE/Vampire/BloodSuckedComponent.cs @@ -0,0 +1,9 @@ +namespace Content.Server.Vampiric +{ + /// + /// For entities who have been succed. + /// + [RegisterComponent] + public sealed partial class BloodSuckedComponent : Component + {} +} diff --git a/Content.Server/_EE/Vampire/BloodSuckerComponent.cs b/Content.Server/_EE/Vampire/BloodSuckerComponent.cs new file mode 100644 index 00000000000..f5619d1cb49 --- /dev/null +++ b/Content.Server/_EE/Vampire/BloodSuckerComponent.cs @@ -0,0 +1,44 @@ +namespace Content.Server.Vampiric +{ + [RegisterComponent] + public sealed partial class BloodSuckerComponent : Component + { + /// + /// How much to succ each time we succ. + /// + [DataField("unitsToSucc")] + public float UnitsToSucc = 20f; + + /// + /// The time (in seconds) that it takes to succ an entity. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public TimeSpan Delay = TimeSpan.FromSeconds(4); + + // ***INJECT WHEN SUCC*** + + /// + /// Whether to inject chems into a chemstream when we suck something. + /// + [DataField("injectWhenSucc")] + public bool InjectWhenSucc = false; + + /// + /// How many units of our injected chem to inject. + /// + [DataField("unitsToInject")] + public float UnitsToInject = 5; + + /// + /// Which reagent to inject. + /// + [DataField("injectReagent")] + public string InjectReagent = ""; + + /// + /// Whether we need to web the thing up first... + /// + [DataField("webRequired")] + public bool WebRequired = false; + } +} diff --git a/Content.Server/_EE/Vampire/BloodSuckerSystem.cs b/Content.Server/_EE/Vampire/BloodSuckerSystem.cs new file mode 100644 index 00000000000..e85f211e74b --- /dev/null +++ b/Content.Server/_EE/Vampire/BloodSuckerSystem.cs @@ -0,0 +1,202 @@ +using Content.Shared.Verbs; +using Content.Shared.Damage; +using Content.Shared.DoAfter; +using Content.Shared.Damage.Prototypes; +using Content.Shared.Interaction; +using Content.Shared.Inventory; +using Content.Shared.Administration.Logs; +using Content.Shared.Vampiric; +using Content.Shared.Cocoon; +using Content.Server.Atmos.Components; +using Content.Server.Body.Components; +using Content.Server.Body.Systems; +using Content.Shared.Chemistry.EntitySystems; +using Content.Server.Popups; +using Content.Server.DoAfter; +using Content.Server.Nutrition.Components; +using Content.Shared.HealthExaminable; +using Robust.Shared.Prototypes; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Utility; + +namespace Content.Server.Vampiric +{ + public sealed class BloodSuckerSystem : EntitySystem + { + [Dependency] private readonly BodySystem _bodySystem = default!; + [Dependency] private readonly SharedSolutionContainerSystem _solutionSystem = default!; + [Dependency] private readonly PopupSystem _popups = default!; + [Dependency] private readonly DoAfterSystem _doAfter = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly StomachSystem _stomachSystem = default!; + [Dependency] private readonly DamageableSystem _damageableSystem = default!; + [Dependency] private readonly InventorySystem _inventorySystem = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; + [Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent>(AddSuccVerb); + SubscribeLocalEvent(OnHealthExamined); + SubscribeLocalEvent(OnDamageChanged); + SubscribeLocalEvent(OnDoAfter); + } + + private void AddSuccVerb(EntityUid uid, BloodSuckerComponent component, GetVerbsEvent args) + { + + var victim = args.Target; + var ignoreClothes = false; + + if (TryComp(args.Target, out var cocoon)) + { + victim = cocoon.Victim ?? args.Target; + ignoreClothes = cocoon.Victim != null; + } + else if (component.WebRequired) + return; + + if (!TryComp(victim, out var bloodstream) || args.User == victim || !args.CanAccess) + return; + + InnateVerb verb = new() + { + Act = () => + { + StartSuccDoAfter(uid, victim, component, bloodstream, !ignoreClothes); // start doafter + }, + Text = Loc.GetString("action-name-suck-blood"), + Icon = new SpriteSpecifier.Texture(new("/Textures/Nyanotrasen/Icons/verbiconfangs.png")), + Priority = 2 + }; + args.Verbs.Add(verb); + } + + private void OnHealthExamined(EntityUid uid, BloodSuckedComponent component, HealthBeingExaminedEvent args) + { + args.Message.PushNewline(); + args.Message.AddMarkup(Loc.GetString("bloodsucked-health-examine", ("target", uid))); + } + + private void OnDamageChanged(EntityUid uid, BloodSuckedComponent component, DamageChangedEvent args) + { + if (args.DamageIncreased) + return; + + if (_prototypeManager.TryIndex("Brute", out var brute) && args.Damageable.Damage.TryGetDamageInGroup(brute, out var bruteTotal) + && _prototypeManager.TryIndex("Airloss", out var airloss) && args.Damageable.Damage.TryGetDamageInGroup(airloss, out var airlossTotal)) + if (bruteTotal == 0 && airlossTotal == 0) + RemComp(uid); + } + + private void OnDoAfter(EntityUid uid, BloodSuckerComponent component, BloodSuckDoAfterEvent args) + { + if (args.Cancelled || args.Handled || args.Args.Target == null) + return; + + args.Handled = TrySucc(uid, args.Args.Target.Value); + } + + public void StartSuccDoAfter(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodSuckerComponent = null, BloodstreamComponent? stream = null, bool doChecks = true) + { + if (!Resolve(bloodsucker, ref bloodSuckerComponent) || !Resolve(victim, ref stream)) + return; + + if (doChecks) + { + if (!_interactionSystem.InRangeUnobstructed(bloodsucker, victim)) + return; + + if (_inventorySystem.TryGetSlotEntity(victim, "head", out var headUid) && HasComp(headUid)) + { + _popups.PopupEntity(Loc.GetString("bloodsucker-fail-helmet", ("helmet", headUid)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + return; + } + + if (_inventorySystem.TryGetSlotEntity(bloodsucker, "mask", out var maskUid) && + EntityManager.TryGetComponent(maskUid, out var blocker) && + blocker.Enabled) + { + _popups.PopupEntity(Loc.GetString("bloodsucker-fail-mask", ("mask", maskUid)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + return; + } + } + + if (stream.BloodReagent != "Blood") + _popups.PopupEntity(Loc.GetString("bloodsucker-not-blood", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + else if (_solutionSystem.PercentFull(victim) != 0) + _popups.PopupEntity(Loc.GetString("bloodsucker-fail-no-blood", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + else + _popups.PopupEntity(Loc.GetString("bloodsucker-doafter-start", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + + _popups.PopupEntity(Loc.GetString("bloodsucker-doafter-start-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); + + var args = new DoAfterArgs(EntityManager, bloodsucker, bloodSuckerComponent.Delay, new BloodSuckDoAfterEvent(), bloodsucker, target: victim) + { + BreakOnMove = true, + DistanceThreshold = 2f, + NeedHand = false + }; + + _doAfter.TryStartDoAfter(args); + } + + public bool TrySucc(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodsuckerComp = null) + { + // Is bloodsucker a bloodsucker? + if (!Resolve(bloodsucker, ref bloodsuckerComp)) + return false; + + // Does victim have a bloodstream? + if (!TryComp(victim, out var bloodstream)) + return false; + + // No blood left, yikes. + if (_bloodstreamSystem.GetBloodLevelPercentage(victim, bloodstream) == 0.0f) + return false; + + // Does bloodsucker have a stomach? + var stomachList = _bodySystem.GetBodyOrganEntityComps((bloodsucker)); + if (stomachList.Count == 0) + return false; + + // Are we too full? + + if (_solutionSystem.PercentFull(bloodsucker) >= 1) + { + _popups.PopupEntity(Loc.GetString("drink-component-try-use-drink-had-enough"), bloodsucker, bloodsucker, Shared.Popups.PopupType.MediumCaution); + return false; + } + + _adminLogger.Add(Shared.Database.LogType.MeleeHit, Shared.Database.LogImpact.Medium, $"{ToPrettyString(bloodsucker):player} sucked blood from {ToPrettyString(victim):target}"); + + // All good, succ time. + _audio.PlayPvs("/Audio/Items/drink.ogg", bloodsucker); + _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); + _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked", ("target", victim)), bloodsucker, bloodsucker, Shared.Popups.PopupType.Medium); + EnsureComp(victim); + + // Make everything actually ingest. + if (bloodstream.BloodSolution == null) + return false; + + var temp = _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSucc); + _stomachSystem.TryTransferSolution(stomachList[0].Owner, temp, stomachList[0]); + + // Add a little pierce + DamageSpecifier damage = new(); + damage.DamageDict.Add("Piercing", 1); // Slowly accumulate enough to gib after like half an hour + + _damageableSystem.TryChangeDamage(victim, damage, true, true); + + //I'm not porting the nocturine gland, this code is deprecated, and will be reworked at a later date. + //if (bloodsuckerComp.InjectWhenSucc && _solutionSystem.TryGetInjectableSolution(victim, out var injectable)) + //{ + // _solutionSystem.TryAddReagent(victim, injectable, bloodsuckerComp.InjectReagent, bloodsuckerComp.UnitsToInject, out var acceptedQuantity); + //} + return true; + } + } +} diff --git a/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs b/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs new file mode 100644 index 00000000000..1a3c9b1588a --- /dev/null +++ b/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs @@ -0,0 +1,23 @@ +namespace Content.Server.Vampiric +{ + [RegisterComponent] + /// + /// Item that gives a bloodsucker injection glands (for poison, usually) + /// + public sealed partial class BloodSuckerGlandInjectorComponent : Component + { + public bool Used = false; + + /// + /// How many units of our injected chem to inject. + /// + [DataField("unitsToInject")] + public float UnitsToInject = 5; + + /// + /// Which reagent to inject. + /// + [DataField("injectReagent")] + public string InjectReagent = ""; + } +} diff --git a/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs b/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs new file mode 100644 index 00000000000..d2a92f24be6 --- /dev/null +++ b/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs @@ -0,0 +1,39 @@ +using Content.Server.Popups; +using Content.Shared.Interaction; + +namespace Content.Server.Vampiric +{ + public sealed class BloodSuckerGlandInjectorSystem : EntitySystem + { + [Dependency] private readonly PopupSystem _popupSystem = default!; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnAfterInteract); + } + + private void OnAfterInteract(EntityUid uid, BloodSuckerGlandInjectorComponent component, AfterInteractEvent args) + { + if (component.Used) + return; + + if (!args.CanReach) + return; + + if (!TryComp(args.Target, out var bloodSuckerComponent)) + return; + + // They already have one. + if (bloodSuckerComponent.InjectWhenSucc) + return; + + bloodSuckerComponent.InjectWhenSucc = true; + bloodSuckerComponent.InjectReagent = component.InjectReagent; + bloodSuckerComponent.UnitsToInject = component.UnitsToInject; + component.Used = true; + QueueDel(uid); + + _popupSystem.PopupEntity(Loc.GetString("bloodsucker-glands-throb"), args.Target.Value, args.Target.Value); + } + } +} diff --git a/Content.Shared/_EE/Cocoon/CocoonComponent.cs b/Content.Shared/_EE/Cocoon/CocoonComponent.cs new file mode 100644 index 00000000000..66ba6e6dd37 --- /dev/null +++ b/Content.Shared/_EE/Cocoon/CocoonComponent.cs @@ -0,0 +1,14 @@ +namespace Content.Shared.Cocoon +{ + [RegisterComponent] + public sealed partial class CocoonComponent : Component + { + public string? OldAccent; + + public EntityUid? Victim; + + [DataField("damagePassthrough")] + public float DamagePassthrough = 0.5f; + + } +} diff --git a/Content.Shared/_EE/Cocoon/CocoonDoAfterEvent.cs b/Content.Shared/_EE/Cocoon/CocoonDoAfterEvent.cs new file mode 100644 index 00000000000..0b9049e9890 --- /dev/null +++ b/Content.Shared/_EE/Cocoon/CocoonDoAfterEvent.cs @@ -0,0 +1,15 @@ +using Robust.Shared.Serialization; +using Content.Shared.DoAfter; + +namespace Content.Shared.Cocoon +{ + [Serializable, NetSerializable] + public sealed partial class CocoonDoAfterEvent : SimpleDoAfterEvent + { + } + + [Serializable, NetSerializable] + public sealed partial class UnCocoonDoAfterEvent : SimpleDoAfterEvent + { + } +} diff --git a/Content.Shared/_EE/Cocoon/CocoonerComponent.cs b/Content.Shared/_EE/Cocoon/CocoonerComponent.cs new file mode 100644 index 00000000000..17cce973096 --- /dev/null +++ b/Content.Shared/_EE/Cocoon/CocoonerComponent.cs @@ -0,0 +1,14 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Cocoon +{ + [RegisterComponent, NetworkedComponent] + public sealed partial class CocoonerComponent : Component + { + [DataField("cocoonDelay")] + public float CocoonDelay = 12f; + + [DataField("cocoonKnockdownMultiplier")] + public float CocoonKnockdownMultiplier = 0.5f; + } +} diff --git a/Content.Shared/_EE/Vampiric/BloodSuckDoAfterEvent.cs b/Content.Shared/_EE/Vampiric/BloodSuckDoAfterEvent.cs new file mode 100644 index 00000000000..6aadc258d73 --- /dev/null +++ b/Content.Shared/_EE/Vampiric/BloodSuckDoAfterEvent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.Serialization; +using Content.Shared.DoAfter; + +namespace Content.Shared.Vampiric +{ + [Serializable, NetSerializable] + public sealed partial class BloodSuckDoAfterEvent : SimpleDoAfterEvent + { + } +} diff --git a/Resources/Locale/en-US/_EE/abilities/arachne.ftl b/Resources/Locale/en-US/_EE/abilities/arachne.ftl new file mode 100644 index 00000000000..f088a4c444c --- /dev/null +++ b/Resources/Locale/en-US/_EE/abilities/arachne.ftl @@ -0,0 +1,16 @@ +action-name-spin-web = Spin Web +action-desc-spin-web = Use your spinnerets to make a spider web in the current tile. Makes you hungrier and thirstier. +action-name-spin-web-space = You can't spin a web in space! +action-name-spin-web-blocked = There's no room for a web here. +spin-web-action-hungry = You're too hungry to spin a web! +spin-web-action-thirsty = You're too thirsty to spin a web! +spin-web-start-second-person = You start spinning a web. +spin-web-start-third-person = {CAPITALIZE(THE($spider))} starts spinning a web! +cocoon-start-second-person = You start cocooning {THE($target)}. +cocoon-start-third-person = {CAPITALIZE(THE($spider))} starts cocooning {THE($target)}. +uncocoon-start-second-person = You start releasing {THE($target)}. +uncocoon-start-third-person = {CAPITALIZE(THE($spider))} starts releasing {THE($target)}. +spun-web-second-person = You spin up a web. +spun-web-third-person = {CAPITALIZE(THE($spider))} spins up a web! +cocoon = Cocoon +uncocoon = Uncocoon diff --git a/Resources/Locale/en-US/_EE/species/species.ftl b/Resources/Locale/en-US/_EE/species/species.ftl new file mode 100644 index 00000000000..174ce96112c --- /dev/null +++ b/Resources/Locale/en-US/_EE/species/species.ftl @@ -0,0 +1,3 @@ +## Species Names + +species-name-arachne = Arachne diff --git a/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml b/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml index 02feda953f8..f473eb48580 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml @@ -76,6 +76,9 @@ ignoreWhitelist: components: - IgnoreSpiderWeb + - type: Tag # DeltaV begin port Arachne from EE + tags: + - ArachneWeb # DeltaV end port Arachne from EE - type: entity id: SpiderWebClown diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Player/arachne.yml b/Resources/Prototypes/_EE/Entities/Mobs/Player/arachne.yml new file mode 100644 index 00000000000..4391fa33fab --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Mobs/Player/arachne.yml @@ -0,0 +1,29 @@ +- type: entity + save: false + name: Urist McArachne + parent: MobArachneBase + id: MobArachne + components: + - type: CombatMode + - type: MindContainer + showExamineInfo: true + - type: Input + context: "human" + - type: MobMover + - type: InputMover + - type: Respirator + damage: + types: + Asphyxiation: 1.0 + damageRecovery: + types: + Asphyxiation: -1.0 + - type: Alerts + - type: Actions + - type: Eye + - type: CameraRecoil + - type: Examiner + - type: CanHostGuardian + - type: NpcFactionMember + factions: + - NanoTrasen diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Species/arachne.yml b/Resources/Prototypes/_EE/Entities/Mobs/Species/arachne.yml new file mode 100644 index 00000000000..54e5fbd3e44 --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Mobs/Species/arachne.yml @@ -0,0 +1,222 @@ +- type: entity + save: false + name: Urist McArachne + parent: BaseMobHuman + id: MobArachneBase + abstract: true + components: + - type: Sprite + # Arachne are one of the species that needs a manual visual layers setup. + layers: + - map: [ "enum.HumanoidVisualLayers.LLeg" ] + sprite: _EE/Mobs/Species/arachne.rsi + state: spider_body + - map: [ "enum.HumanoidVisualLayers.Chest" ] + color: "#e8b59b" + sprite: /Mobs/Species/Human/parts.rsi + state: torso_m + - map: [ "enum.HumanoidVisualLayers.RLeg" ] + sprite: _EE/Mobs/Species/arachne.rsi + state: spider_body_front + - map: [ "enum.HumanoidVisualLayers.Head" ] + color: "#e8b59b" + sprite: /Mobs/Species/Human/parts.rsi + state: head_m + - map: [ "enum.HumanoidVisualLayers.Eyes" ] + color: "#008800" + sprite: _EE/Mobs/Species/eyes.rsi + state: eyes + - map: [ "enum.HumanoidVisualLayers.RArm" ] + color: "#e8b59b" + sprite: /Mobs/Species/Human/parts.rsi + state: r_arm + - map: [ "enum.HumanoidVisualLayers.LArm" ] + color: "#e8b59b" + sprite: /Mobs/Species/Human/parts.rsi + state: l_arm + - shader: StencilClear + sprite: /Mobs/Species/Human/parts.rsi + state: l_leg + - shader: StencilMask + map: [ "enum.HumanoidVisualLayers.StencilMask" ] + sprite: _EE/Mobs/Customization/anytaur_masking_helpers.rsi + state: unisex_full + visible: false + - map: [ "jumpsuit" ] + - map: [ "enum.HumanoidVisualLayers.LHand" ] + color: "#e8b59b" + sprite: /Mobs/Species/Human/parts.rsi + state: l_hand + - map: [ "enum.HumanoidVisualLayers.RHand" ] + color: "#e8b59b" + sprite: /Mobs/Species/Human/parts.rsi + state: r_hand + - map: [ "enum.HumanoidVisualLayers.Handcuffs" ] + color: "#ffffff" + sprite: Objects/Misc/handcuffs.rsi + state: body-overlay-2 + visible: false + - map: [ "id" ] + - map: [ "gloves" ] + - map: [ "shoes" ] + - map: [ "ears" ] + - map: [ "outerClothing" ] + - map: [ "eyes" ] + - map: [ "belt" ] + - map: [ "neck" ] + - map: [ "back" ] + - map: [ "enum.HumanoidVisualLayers.Hair" ] + state: bald + sprite: Mobs/Customization/human_hair.rsi + - map: [ "mask" ] + - map: [ "head" ] + - map: [ "pocket1" ] + - map: [ "pocket2" ] + - map: [ "enum.HumanoidVisualLayers.Tail" ] + sprite: _EEMobs/Customization/masking_helpers.rsi + state: none + visible: false + - map: [ "clownedon" ] # Dynamically generated + sprite: "Effects/creampie.rsi" + state: "creampie_human" + visible: false + - type: HumanoidAppearance + species: Arachne + - type: Fixtures + fixtures: # TODO: This needs a second fixture just for mob collisions. + fix1: + shape: + !type:PhysShapeCircle + radius: 0.40 + density: 140 + restitution: 0.0 + mask: + - MobMask + layer: + - MobLayer + - type: Body + prototype: Arachne + requiredLegs: 8 + - type: Speech + speechSounds: Alto + - type: Inventory + templateId: anytaur + - type: Tag + tags: + - CanPilot + - DoorBumpOpener + - type: Bloodstream + bloodReagent: DemonsBlood + bloodRegenerationThirst: 4 # 1 unit of demon's blood satiates 4 thirst + - type: BloodSucker + webRequired: true + - type: Cocooner + - type: DamageVisuals + targetLayers: + - "enum.HumanoidVisualLayers.Chest" + - "enum.HumanoidVisualLayers.Head" + - "enum.HumanoidVisualLayers.LArm" + - "enum.HumanoidVisualLayers.RArm" + - type: MovedByPressure + pressureResistance: 4 + - type: Barotrauma + damage: + types: + Blunt: 0.05 #per second, scales with pressure and other constants. Reduced Damage. This allows medicine to heal faster than damage. + - type: MovementAlwaysTouching + - type: MovementSpeedModifier + baseWalkSpeed : 3.0 + baseSprintSpeed : 5.0 + - type: FireVisuals + sprite: Mobs/Effects/onfire.rsi + normalState: Generic_mob_burning + alternateState: arachne_standing + fireStackAlternateState: 3 + - type: Spider + - type: IgnoreSpiderWeb +# - type: FootPrints +# leftBarePrint: "footprint-left-bare-spider" +# rightBarePrint: "footprint-right-bare-spider" + +- type: entity + save: false + name: Urist McHands + parent: MobHumanDummy + id: MobArachneDummy + noSpawn: true + description: A dummy arachne meant to be used in character setup. + components: + - type: Sprite + layers: + - map: [ "enum.HumanoidVisualLayers.LLeg" ] + sprite: _EE/Mobs/Species/arachne.rsi + state: spider_body + - map: [ "enum.HumanoidVisualLayers.Chest" ] + color: "#e8b59b" + sprite: /Mobs/Species/Human/parts.rsi + state: torso_m + - map: [ "enum.HumanoidVisualLayers.RLeg" ] + sprite: _EE/Mobs/Species/arachne.rsi + state: spider_body_front + - map: [ "enum.HumanoidVisualLayers.Head" ] + color: "#e8b59b" + sprite: /Mobs/Species/Human/parts.rsi + state: head_m + - map: [ "enum.HumanoidVisualLayers.Eyes" ] + color: "#008800" + sprite: _EE/Mobs/Species/eyes.rsi + state: eyes + - map: [ "enum.HumanoidVisualLayers.RArm" ] + color: "#e8b59b" + sprite: /Mobs/Species/Human/parts.rsi + state: r_arm + - map: [ "enum.HumanoidVisualLayers.LArm" ] + color: "#e8b59b" + sprite: /Mobs/Species/Human/parts.rsi + state: l_arm + - shader: StencilClear + sprite: /Mobs/Species/Human/parts.rsi + state: l_leg + - shader: StencilMask + map: [ "enum.HumanoidVisualLayers.StencilMask" ] + sprite: _EE/Mobs/Customization/anytaur_masking_helpers.rsi + state: unisex_full + visible: false + - map: [ "jumpsuit" ] + - map: [ "enum.HumanoidVisualLayers.LHand" ] + color: "#e8b59b" + sprite: Mobs/Species/Human/parts.rsi + state: l_hand + - map: [ "enum.HumanoidVisualLayers.RHand" ] + color: "#e8b59b" + sprite: Mobs/Species/Human/parts.rsi + state: r_hand + - map: [ "enum.HumanoidVisualLayers.Handcuffs" ] + color: "#ffffff" + sprite: Objects/Misc/handcuffs.rsi + state: body-overlay-2 + visible: false + - map: [ "id" ] + - map: [ "gloves" ] + - map: [ "shoes" ] + - map: [ "ears" ] + - map: [ "outerClothing" ] + - map: [ "eyes" ] + - map: [ "belt" ] + - map: [ "neck" ] + - map: [ "back" ] + - map: [ "enum.HumanoidVisualLayers.Hair" ] + state: bald + sprite: Mobs/Customization/human_hair.rsi + - map: [ "mask" ] + - map: [ "head" ] + - map: [ "pocket1" ] + - map: [ "pocket2" ] + - map: [ "enum.HumanoidVisualLayers.Tail" ] + sprite: Mobs/Customization/masking_helpers.rsi + state: none + visible: false + - type: Inventory + templateId: anytaur + - type: HumanoidAppearance + species: Arachne diff --git a/Resources/Prototypes/_EE/Species/arachne.yml b/Resources/Prototypes/_EE/Species/arachne.yml new file mode 100644 index 00000000000..b50808a28de --- /dev/null +++ b/Resources/Prototypes/_EE/Species/arachne.yml @@ -0,0 +1,59 @@ +- type: species + id: Arachne + name: species-name-arachne + roundStart: true + prototype: MobArachne + sprites: MobArachneSprites + markingLimits: MobArachneMarkingLimits + dollPrototype: MobArachneDummy + skinColoration: HumanToned + sexes: + - Female + minAge: 60 + youngAge: 150 + oldAge: 400 + maxAge: 666 + +- type: markingPoints + id: MobArachneMarkingLimits + points: + Hair: + points: 1 + required: false + Tail: + points: 1 + required: false + Chest: + points: 1 + required: false + RightArm: + points: 2 + required: false + RightHand: + points: 2 + required: false + LeftArm: + points: 2 + required: false + LeftHand: + points: 2 + required: false + + +- type: speciesBaseSprites + id: MobArachneSprites + sprites: + Head: MobHumanHead + Hair: MobHumanoidAnyMarking + Chest: MobHumanTorso + Eyes: MobArachneEyes + LArm: MobHumanLArm + RArm: MobHumanRArm + LHand: MobHumanLHand + RHand: MobHumanRHand + +- type: humanoidBaseSprite + id: MobArachneEyes + baseSprite: + sprite: Mobs/Species/eyes.rsi + state: eyes diff --git a/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/female_full.png b/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/female_full.png new file mode 100644 index 0000000000000000000000000000000000000000..acb96562e7374cbaba2d9f8eac4f1983c2722946 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pW8&%J7@~1LIYA=F!GWQPv*Eu3gIdO!1&Rrbf?NSjtdA<$*!Y?lS%R69 i8<@M9!xb)?)i4xI-eS7+u8$Z{KZB>MpUXO@geCy^0w-qx literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/female_none.png b/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/female_none.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/female_top.png b/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/female_top.png new file mode 100644 index 0000000000000000000000000000000000000000..acb96562e7374cbaba2d9f8eac4f1983c2722946 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pW8&%J7@~1LIYA=F!GWQPv*Eu3gIdO!1&Rrbf?NSjtdA<$*!Y?lS%R69 i8<@M9!xb)?)i4xI-eS7+u8$Z{KZB>MpUXO@geCy^0w-qx literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/full.png b/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/full.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/male_full.png b/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/male_full.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/male_none.png b/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/male_none.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/male_top.png b/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/male_top.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/meta.json b/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/meta.json new file mode 100644 index 00000000000..b44be570c4f --- /dev/null +++ b/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/meta.json @@ -0,0 +1,59 @@ +{ + "version": 1, + "copyright": "Rane", + "license": "CC-BY-SA-3.0", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "female_none", + "directions": 4 + }, + { + "name": "female_full", + "directions": 4 + }, + { + "name": "female_top", + "directions": 4 + }, + { + "name": "male_none", + "directions": 4 + }, + { + "name": "male_full", + "directions": 4 + }, + { + "name": "male_top", + "directions": 4 + }, + { + "name": "full", + "directions": 4 + }, + { + "name": "none", + "directions": 4 + }, + { + "name": "top", + "directions": 4 + }, + { + "name": "unisex_full", + "directions": 4 + }, + { + "name": "unisex_none", + "directions": 4 + }, + { + "name": "unisex_top", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/none.png b/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/none.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/top.png b/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/top.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_full.png b/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_full.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_none.png b/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_none.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_top.png b/Resources/Textures/_EE/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_top.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Species/arachne.rsi/meta.json b/Resources/Textures/_EE/Mobs/Species/arachne.rsi/meta.json new file mode 100644 index 00000000000..a985b24cca3 --- /dev/null +++ b/Resources/Textures/_EE/Mobs/Species/arachne.rsi/meta.json @@ -0,0 +1,19 @@ +{ + "version": 1, + "license": "CC-BY-4.0", + "copyright": "Created by @kes#0001, colored by Woods#1999", + "size": { + "x": 64, + "y": 64 + }, + "states": [ + { + "name": "spider_body", + "directions": 4 + }, + { + "name": "spider_body_front", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/_EE/Mobs/Species/arachne.rsi/spider_body.png b/Resources/Textures/_EE/Mobs/Species/arachne.rsi/spider_body.png new file mode 100644 index 0000000000000000000000000000000000000000..d1432cc3fd6cc1a7173901d236ea01c10ab94225 GIT binary patch literal 3288 zcmaJ^i$4?U8{fupOD;vExwKX!w~3vR`*B+x4jqJC8_G2y_u=QdhDi!-sBluQA^d8z z7>4DZTxMZwCalp=?!Wa1{LcG%pZEKG-skhYpZE4W-}k-eU~h9&OhF6)031cyT3+R2 z$}bTS;?AmD) zKV&O0A!bVljmNy>941fEtUvsNf<#C6hW0m=olpkci}?mrvAw)ZKPf%adVSl#@2XV_ zNH@9fvXirlxucBLztxAgPw}qrjheQjFAxNDeC8Y2Y*K$?d$iZ=(%h30OsCJE3n8ed zG)^i&L_Q6c*>eL3f>_{GAc;Ts+^p8S^t_j|=M!H@Iex3ILfd`SBM(2cg^ykYnujA!~b@^ z%}uMw=R-y4!}yn;09BjgcfeT_K^ZHC8fpFuA6v-E2HsOht4}n*JMK95N556KJej=` zoGYl0n%K{PjD)~nX=ESn>(`NBEYy_#MwI=-{n3+J{BnjHGiM5Qq`k zPkN$;y#*)OmL0c|rcQ`W%HwmbS&7n}K2idh`~D}XEHO2R89pH05d+xwk~FIiyWMi? zMZP;R<@bvGjd^cpjlkg}L7dfuksz26IOV;r zIIwsqKs+AZr3O+__kI-r(hjgf)fM|);>!3&r#0ci&P#16zndZP9fzCrQefXF#?_#T zPf#6dgiZ$ebB^^`5d1<`nWr~_i^D;Y$5KjZhA8ostvpu80j=NCeNa_mI5ELsUh+1M zMRtZ&?o+s=qJBS%Dtf(19;0|=CHUYwReLdyJ4f{%8akM>Z!!To;b7og>oM+T@etd? zq;E#j=FGcUdZX*liLf#@-&Ab`m>(a^?dN$2`EQX5v#&1#ulYOuoY@Z3%{M1eBr&dq zRt=M62g^PPL$+#^yZLjn;P|>xp7Q7Re93Fq7U%5$Vl~LgX~&nfh|K%xN>f^qtrki6 z=XuW+Ouf7b>#-W8_E}F3x7wDOPkK>qLgsfjuNBk7<_B*%DKusS-|S(n)}r-f(w@z6 zB4Q3RMi=hyPS+O8Um3TN9s$Ia6|fBIQ9OFA29Cb49}B(NrX5q3aAcl7dWs)R2;{x; z7ZDG)A35wlF+JQ{N~@ajxrlCGT>dr$&Z8WooEWTno7IrsMt-(ooHyO2YR@RmA7Vuy zQNbF5Vn9DPm(aE~v?ch+-H22=fGs|*KjrCVSia`M6|G}D`N_tt@8eENrYkhn~RmcIp-nIVJyw&TxG#n z+@N~SQVda~Z~F+w=Qgm!80H+DbDG-hehiKh=dUgKOqvnoD3wE-!9RNOUUq0m3{jk74f5fcWADFZ! zy1KEZ6z#LfGf_`LFMyMG`o8C=;o`=*w>9tTvf}&f5#-VLMqaeAo%sRLG{ zQ~QlY7XF(?BW3w^PY>quJ2kV+smcOH4|4=xI@mkY+#^ z#y>65iT#!{oUJslkFlJONCk!`j6+`n5AYAz|Kykky9m$4=!w?mGds;ZXy>Srd?yCA zNbzRr+-z}70rDiPW`hLQ(a$UKP7E2ypSV%>G)xclv9EvOS(JptdwB+8VZ125_uF4t ze*`LnM_y_0{ZY9nO}xOzZvIs-W2V3?`O(G$YQ0N@If4t2_C)&PZbketvk?)8Bi!DC z8^(V4W0?yTBi?fS9rqEJ^IkW^T%!`#T|X~l{r{C>|BZnCO@k8V=ZSSUzi?#!kovh{ zA!)zY!D~&_ff|KBgq2J>ncQyBj%#!7squaoi|&qs3rxiYwSG@-PFnIK%_XlwQN=~k zzaeOUh$k3p&H`{N{Pb#oK*UB6I(^LW&)Y9rFJI+wOJgeX|66~hdHRb_P2WcA`p&*d zApV$Or&sdIv_zcgW6TQTwR;_9C|RnNfjEc!J8_P^`dc-2zbw{NNp2{4pk5MF@j|LI zVmpLratY+x>*IE!(BJvDGT=;b58iH}4@d7zm-ZZH8e_2YfuH|6H@0cyUgzRZxhwj3 zGx)W$XZOPv!7bQgvy$AQHidFSUyOazt<^vZWy>grBBLeLag6HNa`xN34QAes155Z9 zGTvx8AmF$ogivq4K)e&_df{~Aex&m0Lyh&lg$*YFn4(qf1u~afg{EFQ>-bbnQ#+M| zcrEFE=`8PnIh>sINP1!Ja6|P!W1>Rk2;UZuRM>0$pbgyPB4IGxvklwS86o<9PFwph z@RG>|(B6-pjDB8;k=%Eqn~knIN)m5KBvtI0ay7=mK^X#vVKO?n+G}WKOA)e&)X>l{ zaQaO~qNWVHz0q9WS|ydc`}2U2zhABfQJ>4RIdkG&-j}!ueIv^DE1Mpv{1PK7cAzlM zabc`AbT1>1yPIP}X6$!ST0?uu(hv(Lm*Jh*q@mGRkCXG8j)=osMvKhtI7b(_xU_UH zd9=4Md#v!Fw~z)O=7IC~rft?&p=;!cmN-*|{&UFwb+q#29jtDUZ#s&mN3aXv8RTa6 z#Oi(7**cM8-jJs(_@_0qnxlUjWW$6dNsVx~{`>Zg5VloEY#se1slf*S+|oB4GjAyI zj?0`!w6FjCgi=2B9sqPS2wXDeQpOX~f~e~uQUd$nbgG(y3G8*h~$O+~zC znN4>r9L4lS3Rg1g#+K%bI7zQ6ef6VfQmR9Cf>Fe%T9SV8ajQ|>AeX*N=a)BWp7=Fl%v!`VfoB$a@7}%n8?8I^dNW8q=HYiUgU^ zZ}x+J(dV-Wx+jOMetM>d+2uaQn_=h&r|*d9G#jE$5kLL%_vmkGkkBwAQXD;Fg{OiP4?B+GjM(d@-4D zR~@mu+0AQD4qu@xO6PZNB`8roBj>xk!;PPC)7LEI?F?Iw@(c>T`%Ru51J<)6BR33% z0qTi!!Y@`;S$XU@k-oviFvHgU%8CYdWSaSw=h!*~&GlQszB~U{7(JS2rZJ!;$=P_Q zDf@qt)4}ft!t9(X_L#mYhW{av@OMQ9*x3Qp`ML;SewDGm3w{C8%HFcx!YB2Ax^hzn literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Species/arachne.rsi/spider_body_front.png b/Resources/Textures/_EE/Mobs/Species/arachne.rsi/spider_body_front.png new file mode 100644 index 0000000000000000000000000000000000000000..0171f16fe385fe420c6f1b1142b5381e2284ba92 GIT binary patch literal 761 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSoCO|{#S9F5M?jcysy3fA0|V1U zPZ!6KiaBrZ9`qM>6gmF!{+8Vi+G2O6t>rz%CBtGXu=nNv`4z?wm8z7c6lHq3>b})` z_pMSxSHic)aOSLUzju~yJ9%bb<>#{RUsQlrUqp7-u2zqhRC<9m~TO#Ecr>eQ`KzJ5W|QoS~ZL{9TeyS3u#mg`xS{f-Zc zH_f%!X2A2MsQ$i*T>MNm)e}>_W+zHysQ0bC`&KU}RO?vs)5>*@^G?6XTR*qBXwtFA z8^4=YdN(}xOj>-=W3fqaYOe1jv*p+4EHOEo_W!p@d(eyKnVA+ct77#2PhxNl{A2R0 zdpb*n)NwJE$t#b!F0?ssYWp|XHPA;)WQzDUp%86RR>uVfJSFu&(@%YlIrnpaYQAWK zDo<#?QtY?iRXg^r%WppT=GK>T+b$K|ce7vG#C`gA#G7eO`R;X3=3HIuan6#L?fS0z zL&DF`SgJptqxZXZuI_`E?Ms&2+_L26pSR6=nPzVzKYu(_&xt({v4}Q2eYn;6dH3B| zW8+XQ(Y^MT3$0(+uIJ~^HIX`LxtxFb@_R{-x7O}C6S6jJ>n@>JZ!cb4Q~zoA3IjA^m*&&Ubxth`@pA}Idyk3R@{B*k#_1*$lJK{*`{;6U*7GLyP1~j zeE)L{|Ekc^YTMW^zrDXo+~`y4mgbG+Z|7=u2#??YV$uJ~l}VU>`gfN9lgpc9^P48s h0VVlTBRtc5eHpZXY!0a6OTm*tEKgTImvv4FO#o58J(mCg literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Species/eyes.rsi/eyes.png b/Resources/Textures/_EE/Mobs/Species/eyes.rsi/eyes.png new file mode 100644 index 0000000000000000000000000000000000000000..b6250e22b38a17c35b2b54789f66bb5cda1db308 GIT binary patch literal 5553 zcmeHLd010d77wzDfU+qtI*oAw(U<*YD`7_yA&4vjF4dQp7kGv&B!L86pehy>DYz6x z+^PsjQNew*D4Cj1VsF%-#4G%wDXtA_mcO{J?D4N`JHp_ z&CRB;(0R7jZq@_>!B!{;3+LUzb6pP>{BCSwBd-3s8TDXcmhV$rl>F? zrpKiOg8ti|qUGBuD6e4r(()_S&dwh;ly&Ze7H8ZK$ViEwy6j9e**Q+o+j(Hzfqlr7^SjpC9IQV%`BOpX zfO%S`qVsQUulSx7YzMcD6zl6B7g_DM%N*ngezo(8rP~N?em%Ej+ruBmI=t{)&=d9e zcK#&iwRY?^E(@D7~|K?a=iT2gR2*G zdfny4mCl)V7c}OVcJUikHM_grZ(g=4n_Yst_a^!*ZzxT#YK#313eS0%?0+h7(BtET z&&@ZE{o(vFL9KbZ6Y|U~PH>qJGflYT$1v#(f0C_P)VT(S^BPTyHs`{Kv) zqJ0;VI|?6E1z5a9+YZ*ubxpc+B|Jaz$nK)hJ=pz>!ZXvqICrNmIIpbYS^c*`9eMq> z_n(TlvLh75Y*~EN8sD57LUn_$%O`>rOZSeM6QA5*cgUr2x27Sx`l0it7KysSf{U)8 zhCVsN_x-Ev(aDJ`fTizb~a_~yBBbx|7)MJiYTAX z${j7yQ-1#JlH~@%{TC?Tog%{_eMYe6`i-&=n%cYkCx6twE*H6yf(+=*d zUPwRicml_2f;O%!Ilj@MI_!Ms;?t+&nFY=c6=!yOo;sq|Om5()&(;+P!cP1!n45sM z%&~C0*4lLLgqhmvFwxyXa=rZftoW;F$85=@w5cA5XY}(M+b3e#@W}_OWL8CE107k1 zgnqYNez`>z*IxXjb^Vmu8553vAzNK7>*$!grjGxp^)@Z71?kNb^qcgV^bHbPIwU)O zVRMW4>tnjNmk%{>q2?c9%`GOi>myOLwHivuKP0W3gbC4H1!8!4s zr_(|IV&}z4)blUL=QF3zB4@9YRaNc3dUXAklgI3itt0lDK6%=9_$g_|+B~PlSM;i; znpHiOJ&$zhUl&vBpSf8wAF=LU->|E`Y%~A3)zr;?1e4vd*9xW=KK`(>%l>i4vVyo* z`};L7OH#JnhDp!oFhcg|*XvX7vN%6G&WjN)+H`AEZHQ-1Z*IrtT4li&@;EPsSbC@X zioLk}Vby%gliNz{7ueTEii%cG?I^EH*>ZAGN%^9^0~swBD=Tg$<<|(r_Q5$se?MC+ za>caJ($LKr%%9v>4=j8@$qk+w?V2@tT(ST9&c3R_$2w(Mb=!tKr%=KpN_IDG%*)O( z_5WyH{lSN!-DXzarqQY2EteA*`wu_(ZgHp8(`F0uvG4LLESGi>0v2pcs5|C#c$Sm( z<$l*S5q2);%>88_H81YxtRc|vmEN;esjRXl&RX^8pO3!WyQaSV6v9K5axx-OiZQZYt^$iWf#Bt%S0Shj(-Os49IoJ#e!g&tM8qY0QZy{0 zic|quJT6F8V-cyLk!Y$66onSiLki6_1H=$UAf`dpxJrvF6+{CjB3348`6Ln;C%*Pit`dnx z;1!x-762a*flMXRxFau$5 zVLF$Nje=O9#z9pg38TF-KuG`;gUM#oq%01^kuWfb$v|L;!(qb^Mx((jHj6Ex(`ZI0 z3Cf$RRLc>NPF#+}VHA}j&NyHooaYxNKjQ|0-}`y13oDPS0w4*3`F8`EJBMI z*rc&oEDjw+%waKL7M=b^X%VK@fJ!uA(x_y{(1;-|JP-^Z7BSQ*05DpBSa<AX+34(P99UN~iN^R34obN#pRCR36NMs7xMpl)h4eOH=-v zwxM~5UPCDt;2JQ0icvJwQ4v_;(9_Uk0&Z+2BGK3sJOmvIL4zb?5~H60YiJ0KM-*`w zSUrZz^|c)TgHk}aAaM+a7~-(#42X%M5(r_#bchWjTqX=^gpEqyM%O5%S{hO3Fe3#1?;+Abh}8dIh-@ZXOA&A*^9*Qt$bo hzP5mNy-}2IJLTr*?u{XN5l)6@VNht`G5;0o{taf-31t8P literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Species/eyes.rsi/meta.json b/Resources/Textures/_EE/Mobs/Species/eyes.rsi/meta.json new file mode 100644 index 00000000000..a98aba406f1 --- /dev/null +++ b/Resources/Textures/_EE/Mobs/Species/eyes.rsi/meta.json @@ -0,0 +1,15 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Created by @Rane#7518", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "eyes", + "directions": 4 + } + ] +} From ea42b14f174f861c911a92077d37ab350c28631a Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Tue, 14 Jan 2025 01:16:49 -0500 Subject: [PATCH 02/26] sppoder --- .../Locale/en-US/_EE/markings/tatoos.ftl | 5 ++ .../Entities/Body/Parts/spider.yml | 30 ++++++-- .../Entities/Body/Prototypes/arachne.yml | 64 ++++++++++++++++++ Resources/Prototypes/_EE/Species/arachne.yml | 20 ++++-- .../masking_helpers.rsi/female_full.png | Bin 0 -> 134 bytes .../masking_helpers.rsi/female_none.png | Bin 0 -> 1568 bytes .../masking_helpers.rsi/female_top.png | Bin 0 -> 130 bytes .../masking_helpers.rsi/full.png | Bin 0 -> 1625 bytes .../masking_helpers.rsi/male_full.png | Bin 0 -> 1625 bytes .../masking_helpers.rsi/male_none.png | Bin 0 -> 1568 bytes .../masking_helpers.rsi/male_top.png | Bin 0 -> 1568 bytes .../masking_helpers.rsi/meta.json | 56 +++++++++++++++ .../masking_helpers.rsi/none.png | Bin 0 -> 83 bytes .../Customization/masking_helpers.rsi/top.png | Bin 0 -> 1625 bytes .../masking_helpers.rsi/unisex_full.png | Bin 0 -> 1625 bytes .../masking_helpers.rsi/unisex_none.png | Bin 0 -> 1568 bytes .../masking_helpers.rsi/unisex_top.png | Bin 0 -> 1568 bytes .../Customization/spidereyes.rsi/eyes.png | Bin 0 -> 5070 bytes .../Customization/spidereyes.rsi/meta.json | 15 ++++ 19 files changed, 179 insertions(+), 11 deletions(-) create mode 100644 Resources/Locale/en-US/_EE/markings/tatoos.ftl create mode 100644 Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml create mode 100644 Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/female_full.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/female_none.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/female_top.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/full.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/male_full.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/male_none.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/male_top.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/meta.json create mode 100644 Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/none.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/top.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/unisex_full.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/unisex_none.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/unisex_top.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/spidereyes.rsi/eyes.png create mode 100644 Resources/Textures/_EE/Mobs/Customization/spidereyes.rsi/meta.json diff --git a/Resources/Locale/en-US/_EE/markings/tatoos.ftl b/Resources/Locale/en-US/_EE/markings/tatoos.ftl new file mode 100644 index 00000000000..6e96ffed129 --- /dev/null +++ b/Resources/Locale/en-US/_EE/markings/tatoos.ftl @@ -0,0 +1,5 @@ +marking-TattooEyeArachneRight-tattoo_eye_arachne_r = Right Arachne Eye +marking-TattooEyeArachneRight = Right Arachne Eye + +marking-TattooEyeArachneLeft-tattoo_eye_arachne_l = Left Arachne Eye +marking-TattooEyeArachneLeft = Left Arachne Eye diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml b/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml index a900f7524e7..f642c8f27c4 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml @@ -5,7 +5,7 @@ abstract: true components: - type: Damageable - damageContainer: Biological + damageContainer: OrganicPart - type: BodyPart - type: ContainerContainer containers: @@ -15,7 +15,7 @@ price: 100 - type: Tag tags: - - Trash + - Trash - type: Extractable juiceSolution: reagents: @@ -24,13 +24,33 @@ - ReagentId: DemonsBlood Quantity: 10 +- type: entity + id: ThoraxSpider + name: "spider thorax" #for arachne, actual spiders should get a cephalothorax that combines with head. + parent: PartSpider + components: + - type: Sprite + sprite: Mobs/Species/Moth/parts.rsi # placeholder sprite + state: "torso_m" + - type: Icon + sprite: Mobs/Species/Moth/parts.rsi + state: "torso_m" + - type: BodyPart #"Other" type + - type: Extractable + juiceSolution: + reagents: + - ReagentId: Fat + Quantity: 10 + - ReagentId: DemonsBlood + Quantity: 20 + - type: entity id: RightLegSpider name: "right spider leg" parent: PartSpider components: - type: Sprite - sprite: Objects/Consumable/Food/meat.rsi + sprite: Objects/Consumable/Food/meat.rsi # placeholder sprite state: spiderleg - type: Icon sprite: Objects/Consumable/Food/meat.rsi @@ -48,7 +68,7 @@ parent: PartSpider components: - type: Sprite - sprite: Objects/Consumable/Food/meat.rsi + sprite: Objects/Consumable/Food/meat.rsi # placeholder sprite state: spiderleg - type: Icon sprite: Objects/Consumable/Food/meat.rsi @@ -56,6 +76,6 @@ - type: BodyPart partType: Leg symmetry: Left - - type: MovementBodyPart #should actual spiders get a seperate part from arachne? + - type: MovementBodyPart # should actual spiders get a seperate part from arachne? walkSpeed : 2.7 sprintSpeed : 5 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml b/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml new file mode 100644 index 00000000000..d8eb35629bf --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml @@ -0,0 +1,64 @@ +- type: body + id: Arachne + name: "arachne" + root: torso + slots: + head: + part: HeadHuman + connections: + - torso + organs: + brain: OrganHumanBrain + eyes: OrganHumanEyes + torso: + part: TorsoHuman + connections: + - left arm + - right arm + - thorax + - head + organs: + heart: OrganHumanHeart + lungs: OrganHumanLungs + stomach: OrganVampiricHumanoidStomach + liver: OrganHumanLiver + kidneys: OrganHumanKidneys + right arm: + part: RightArmHuman + connections: + - right hand + left arm: + part: LeftArmHuman + connections: + - left hand + right hand: + part: RightHandHuman + left hand: + part: LeftHandHuman + thorax: + part: ThoraxSpider + connections: + - left foreleg + - left second leg + - left third leg + - left hind leg + - right foreleg + - right second leg + - right third leg + - right hind leg + left foreleg: + part: LeftLegSpider + left second leg: + part: LeftLegSpider + left third leg: + part: LeftLegSpider + left hind leg: + part: LeftLegSpider + right foreleg: + part: RightLegSpider + right second leg: + part: RightLegSpider + right third leg: + part: RightLegSpider + right hind leg: + part: RightLegSpider diff --git a/Resources/Prototypes/_EE/Species/arachne.yml b/Resources/Prototypes/_EE/Species/arachne.yml index b50808a28de..08be5d27728 100644 --- a/Resources/Prototypes/_EE/Species/arachne.yml +++ b/Resources/Prototypes/_EE/Species/arachne.yml @@ -4,15 +4,13 @@ roundStart: true prototype: MobArachne sprites: MobArachneSprites + defaultSkinTone: "#c0967f" markingLimits: MobArachneMarkingLimits dollPrototype: MobArachneDummy skinColoration: HumanToned + femaleFirstNames: names_arachnid_first sexes: - Female - minAge: 60 - youngAge: 150 - oldAge: 400 - maxAge: 666 - type: markingPoints id: MobArachneMarkingLimits @@ -20,6 +18,12 @@ Hair: points: 1 required: false + FacialHair: + points: 1 + required: false + HeadSide: + points: 3 + required: false Tail: points: 1 required: false @@ -30,13 +34,13 @@ points: 2 required: false RightHand: - points: 2 + points: 3 required: false LeftArm: points: 2 required: false LeftHand: - points: 2 + points: 3 required: false @@ -44,7 +48,11 @@ id: MobArachneSprites sprites: Head: MobHumanHead + Face: MobHumanoidAnyMarking + HeadSide: MobHumanoidAnyMarking Hair: MobHumanoidAnyMarking + FacialHair: MobHumanoidAnyMarking + Snout: MobHumanoidAnyMarking Chest: MobHumanTorso Eyes: MobArachneEyes LArm: MobHumanLArm diff --git a/Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/female_full.png b/Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/female_full.png new file mode 100644 index 0000000000000000000000000000000000000000..cd5127bc90d33fa35476e9aac9810b0c76acc749 GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pqvz@37@~1LIYA=F!GWRaBuh_#4GRNzM?iy+j=*_ig8~5_g&9&3%rX%& c%#Ya_Zly82-n{&4FimdKI;Vst0PTMzC;$Ke literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/female_none.png b/Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/female_none.png new file mode 100644 index 0000000000000000000000000000000000000000..44e0c1358d805be4b575d5a9acf1fd4f0e4ff5bf GIT binary patch literal 1568 zcmV+*2H*LKP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-_Zk|ZY#{pS=u0+Im1ao7~$8~FHskV|hh?XLFx zOhhM91xbphW2 z3Gqp%Q^g- zb7$FmS(FQR@j?=u1PNrUQe;RLmd;ZIyL{V1TW{IwI%Oyx1W6`<5l-ykuEqZy4}r}3 z3K7BkD^{?JdC@>Cin9J81wzQKJc>KO*LZ({SbzjbtuSXeSbaMnTBMiU61RyK2u94| zIIQCYK!~6_!Wa@T;1fxtL|&Pd2yx8dr^0d;7r21}ijfDbXOy-qM?SVu zLLeea5(PCyD!2+E2Gp8{j2x;_Vu&%Os4>S9YmyXFOetwvwOCa&Xw;;tS&P;zIpmmA z)|_+6)fFy+T8$+YExD9ZE0k6sSDdc7Vxw`B7FuknY0Is&+L1mz^w?9^o_p!l4IVPW zh$9Uhd6ZEnO{CHcGtM-1=2>Pnq?(BZi;IDRYZoBagj4pZwpE5Js9sQh5SY1gh6F!1yJrvl z0R34&ZFrefw1;7qqYCn65O#8;`4XbSDXjXX~NO!xA~*MjhPalAhUPsh|^Pu ze*Ha~-LD>a_z7zSh6ux=(Z;%`YDXmBr=~m7>3iAqDlx&@XPiDU{{a0KAVELG*T%nv zTU}7`>gR|600Dz(LqkwWLqi~Na&Km7Y-Iodc$|HaJxIeq9K~PLN<}IT?I7Zip>?t# zD&i2R|084ld5RI=Bjg;0K7Si<6>@l=#1-&?3fz z<9@um_qclp2(21Z&AMYAac;(;P(-OGqIN5i%O6q6Q0b zS~XHkWN1I(;U97QX>!Trs)CVY0d=U596$IU{O;B)O-;H<3+`T*pptK}Qu;1C!qQ}(*YyZd{4`}a(zzaK9ea*XFW7M%b900~e`R7C&) zH2?qr|NsAahD9d;0004WQchCF6XU=)l3@&Et?KmY+L Sjp0=Q0000@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pqvh%17@~1LIYA=F!GWQv-9CX)kSm~x^-(1o8($M6OE7bC19NwB!XE~P Y>pcuFdpA6>0P14!boFyt=akR{0B)-!)c^nh literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/full.png b/Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/full.png new file mode 100644 index 0000000000000000000000000000000000000000..f78008f58a26fea7acd3c9fce0f5eb8280549e6a GIT binary patch literal 1625 zcmV-f2B!ImP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|ca^pA*{O2k52n0azaU8x-H8J213q+{qsxli z!;N!9Xm8CkdOvETScR6yvm8LCe1S?kM=-yKiWn3NeW{3N)ya(cFEf4i^JY zPUx9C%bv@UxNsLQB*96LK*mXm49UXMd5U0`FJEY{TlR9DG8P^LOD2F3p4iQugMZuJ z1TyO@Lkgq&vW8dwD@vfCN~rFlP{~z8w%v>3434+d>Nr z6@54!PU8lE5MgbFGbB*JM-rt-J~1aE#4$sk3eQJte^ocWSI#ZzzC$^;q=QW0R@ z*A0r^g0~#83nkek?Pk%{gql#rT97$xDt@*O=q52PK#SC*;LaF~8}m<2yN_AmtiE`l zx*SYSA{PzU)?2`*Sm5R44I1u_$1-`2$A_w2l-6mxDCKccS{`kGnopb59Ha zT7|Ks+nEKHt0=bf$U4d*T+4b@MH6RV&&UVj?zzL}1@XtSj8`}tu7JXfal^o7z0VDu zo`U-I^>pvnAZ`A0$j%92_%qr#=BU~c($}f^kWcPRs3-I3E;(PFB40axet^CUNRUni ze+&KrpXr8K1+H=f0004lX+uL$Nkc;*aB^>EX>4Tx0C=2zkv&MmKpe$i(@I4u4(%Y~ zkfC+5AS&W0RV;#q(pG5I!Q|2}Xws0RxHt-~1qVMCs}3&Cx;nTDg5U>;tBaGOi0F(9}L zw41j5eQew96TtrrTxnf@y#>sElHTlU(Ia4J8@RacYVsa%xdRM8>5?HilAoqfDgp0j z^i2gIdpp00001bW%=J06^y0W&i*H0b)x>L;#2d9Y_EG010qNS#tmY z3ljhU3ljkVnw%H_000McNliru=K~V}2m}o+O)3BY01`<=K~y-)V_+BsqhJ(_0`dR= X1V8`*DUIP(00000NkvXXu0mjfh;rUK literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/male_full.png b/Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/male_full.png new file mode 100644 index 0000000000000000000000000000000000000000..f78008f58a26fea7acd3c9fce0f5eb8280549e6a GIT binary patch literal 1625 zcmV-f2B!ImP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|ca^pA*{O2k52n0azaU8x-H8J213q+{qsxli z!;N!9Xm8CkdOvETScR6yvm8LCe1S?kM=-yKiWn3NeW{3N)ya(cFEf4i^JY zPUx9C%bv@UxNsLQB*96LK*mXm49UXMd5U0`FJEY{TlR9DG8P^LOD2F3p4iQugMZuJ z1TyO@Lkgq&vW8dwD@vfCN~rFlP{~z8w%v>3434+d>Nr z6@54!PU8lE5MgbFGbB*JM-rt-J~1aE#4$sk3eQJte^ocWSI#ZzzC$^;q=QW0R@ z*A0r^g0~#83nkek?Pk%{gql#rT97$xDt@*O=q52PK#SC*;LaF~8}m<2yN_AmtiE`l zx*SYSA{PzU)?2`*Sm5R44I1u_$1-`2$A_w2l-6mxDCKccS{`kGnopb59Ha zT7|Ks+nEKHt0=bf$U4d*T+4b@MH6RV&&UVj?zzL}1@XtSj8`}tu7JXfal^o7z0VDu zo`U-I^>pvnAZ`A0$j%92_%qr#=BU~c($}f^kWcPRs3-I3E;(PFB40axet^CUNRUni ze+&KrpXr8K1+H=f0004lX+uL$Nkc;*aB^>EX>4Tx0C=2zkv&MmKpe$i(@I4u4(%Y~ zkfC+5AS&W0RV;#q(pG5I!Q|2}Xws0RxHt-~1qVMCs}3&Cx;nTDg5U>;tBaGOi0F(9}L zw41j5eQew96TtrrTxnf@y#>sElHTlU(Ia4J8@RacYVsa%xdRM8>5?HilAoqfDgp0j z^i2gIdpp00001bW%=J06^y0W&i*H0b)x>L;#2d9Y_EG010qNS#tmY z3ljhU3ljkVnw%H_000McNliru=K~V}2m}o+O)3BY01`<=K~y-)V_+BsqhJ(_0`dR= X1V8`*DUIP(00000NkvXXu0mjfh;rUK literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/male_none.png b/Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/male_none.png new file mode 100644 index 0000000000000000000000000000000000000000..44e0c1358d805be4b575d5a9acf1fd4f0e4ff5bf GIT binary patch literal 1568 zcmV+*2H*LKP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-_Zk|ZY#{pS=u0+Im1ao7~$8~FHskV|hh?XLFx zOhhM91xbphW2 z3Gqp%Q^g- zb7$FmS(FQR@j?=u1PNrUQe;RLmd;ZIyL{V1TW{IwI%Oyx1W6`<5l-ykuEqZy4}r}3 z3K7BkD^{?JdC@>Cin9J81wzQKJc>KO*LZ({SbzjbtuSXeSbaMnTBMiU61RyK2u94| zIIQCYK!~6_!Wa@T;1fxtL|&Pd2yx8dr^0d;7r21}ijfDbXOy-qM?SVu zLLeea5(PCyD!2+E2Gp8{j2x;_Vu&%Os4>S9YmyXFOetwvwOCa&Xw;;tS&P;zIpmmA z)|_+6)fFy+T8$+YExD9ZE0k6sSDdc7Vxw`B7FuknY0Is&+L1mz^w?9^o_p!l4IVPW zh$9Uhd6ZEnO{CHcGtM-1=2>Pnq?(BZi;IDRYZoBagj4pZwpE5Js9sQh5SY1gh6F!1yJrvl z0R34&ZFrefw1;7qqYCn65O#8;`4XbSDXjXX~NO!xA~*MjhPalAhUPsh|^Pu ze*Ha~-LD>a_z7zSh6ux=(Z;%`YDXmBr=~m7>3iAqDlx&@XPiDU{{a0KAVELG*T%nv zTU}7`>gR|600Dz(LqkwWLqi~Na&Km7Y-Iodc$|HaJxIeq9K~PLN<}IT?I7Zip>?t# zD&i2R|084ld5RI=Bjg;0K7Si<6>@l=#1-&?3fz z<9@um_qclp2(21Z&AMYAac;(;P(-OGqIN5i%O6q6Q0b zS~XHkWN1I(;U97QX>!Trs)CVY0d=U596$IU{O;B)O-;H<3+`T*pptK}Qu;1C!qQ}(*YyZd{4`}a(zzaK9ea*XFW7M%b900~e`R7C&) zH2?qr|NsAahD9d;0004WQchCF6XU=)l3@&Et?KmY+L Sjp0=Q0000 zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-_Zk|ZY#{pS=u0+Im1ao7~$8~FHskV|hh?XLFx zOhhM91xbphW2 z3Gqp%Q^g- zb7$FmS(FQR@j?=u1PNrUQe;RLmd;ZIyL{V1TW{IwI%Oyx1W6`<5l-ykuEqZy4}r}3 z3K7BkD^{?JdC@>Cin9J81wzQKJc>KO*LZ({SbzjbtuSXeSbaMnTBMiU61RyK2u94| zIIQCYK!~6_!Wa@T;1fxtL|&Pd2yx8dr^0d;7r21}ijfDbXOy-qM?SVu zLLeea5(PCyD!2+E2Gp8{j2x;_Vu&%Os4>S9YmyXFOetwvwOCa&Xw;;tS&P;zIpmmA z)|_+6)fFy+T8$+YExD9ZE0k6sSDdc7Vxw`B7FuknY0Is&+L1mz^w?9^o_p!l4IVPW zh$9Uhd6ZEnO{CHcGtM-1=2>Pnq?(BZi;IDRYZoBagj4pZwpE5Js9sQh5SY1gh6F!1yJrvl z0R34&ZFrefw1;7qqYCn65O#8;`4XbSDXjXX~NO!xA~*MjhPalAhUPsh|^Pu ze*Ha~-LD>a_z7zSh6ux=(Z;%`YDXmBr=~m7>3iAqDlx&@XPiDU{{a0KAVELG*T%nv zTU}7`>gR|600Dz(LqkwWLqi~Na&Km7Y-Iodc$|HaJxIeq9K~PLN<}IT?I7Zip>?t# zD&i2R|084ld5RI=Bjg;0K7Si<6>@l=#1-&?3fz z<9@um_qclp2(21Z&AMYAac;(;P(-OGqIN5i%O6q6Q0b zS~XHkWN1I(;U97QX>!Trs)CVY0d=U596$IU{O;B)O-;H<3+`T*pptK}Qu;1C!qQ}(*YyZd{4`}a(zzaK9ea*XFW7M%b900~e`R7C&) zZU6uP|NsA3RQPHD0004WQchCF6XU=)l3@&Et?KmY+L Sjp0=Q0000B?Wc})uc*XMaS bfSB*u1QZw;C7n&)0XYnwu6{1-oD!M zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|ca^pA*{O2k52n0azaU8x-H8J213q+{qsxli z!;N!9Xm8CkdOvETScR6yvm8LCe1S?kM=-yKiWn3NeW{3N)ya(cFEf4i^JY zPUx9C%bv@UxNsLQB*96LK*mXm49UXMd5U0`FJEY{TlR9DG8P^LOD2F3p4iQugMZuJ z1TyO@Lkgq&vW8dwD@vfCN~rFlP{~z8w%v>3434+d>Nr z6@54!PU8lE5MgbFGbB*JM-rt-J~1aE#4$sk3eQJte^ocWSI#ZzzC$^;q=QW0R@ z*A0r^g0~#83nkek?Pk%{gql#rT97$xDt@*O=q52PK#SC*;LaF~8}m<2yN_AmtiE`l zx*SYSA{PzU)?2`*Sm5R44I1u_$1-`2$A_w2l-6mxDCKccS{`kGnopb59Ha zT7|Ks+nEKHt0=bf$U4d*T+4b@MH6RV&&UVj?zzL}1@XtSj8`}tu7JXfal^o7z0VDu zo`U-I^>pvnAZ`A0$j%92_%qr#=BU~c($}f^kWcPRs3-I3E;(PFB40axet^CUNRUni ze+&KrpXr8K1+H=f0004lX+uL$Nkc;*aB^>EX>4Tx0C=2zkv&MmKpe$i(@I4u4(%Y~ zkfC+5AS&W0RV;#q(pG5I!Q|2}Xws0RxHt-~1qVMCs}3&Cx;nTDg5U>;tBaGOi0F(9}L zw41j5eQew96TtrrTxnf@y#>sElHTlU(Ia4J8@RacYVsa%xdRM8>5?HilAoqfDgp0j z^i2gIdpp00001bW%=J06^y0W&i*H0b)x>L;#2d9Y_EG010qNS#tmY z3ljhU3ljkVnw%H_000McNliru=K~V}2m}o+O)3BY01`<=K~y-)V_+BsqhJ(_0`dR= X1V8`*DUIP(00000NkvXXu0mjfh;rUK literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/unisex_full.png b/Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/unisex_full.png new file mode 100644 index 0000000000000000000000000000000000000000..1b69c04a7a3fef8e75bd6a789149a9bac380174f GIT binary patch literal 1625 zcmV-f2B!ImP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|ca^pA*{O2k52n0azaU8x-H8J213q+{qsxli z!;N!9Xm8CkdOvETScR6yvm8LCe1S?kM=-yKiWn3NeW{3N)ya(cFEf4i^JY zPUx9C%bv@UxNsLQB*96LK*mXm49UXMd5U0`FJEY{TlR9DG8P^LOD2F3p4iQugMZuJ z1TyO@Lkgq&vW8dwD@vfCN~rFlP{~z8w%v>3434+d>Nr z6@54!PU8lE5MgbFGbB*JM-rt-J~1aE#4$sk3eQJte^ocWSI#ZzzC$^;q=QW0R@ z*A0r^g0~#83nkek?Pk%{gql#rT97$xDt@*O=q52PK#SC*;LaF~8}m<2yN_AmtiE`l zx*SYSA{PzU)?2`*Sm5R44I1u_$1-`2$A_w2l-6mxDCKccS{`kGnopb59Ha zT7|Ks+nEKHt0=bf$U4d*T+4b@MH6RV&&UVj?zzL}1@XtSj8`}tu7JXfal^o7z0VDu zo`U-I^>pvnAZ`A0$j%92_%qr#=BU~c($}f^kWcPRs3-I3E;(PFB40axet^CUNRUni ze+&KrpXr8K1+H=f0004lX+uL$Nkc;*aB^>EX>4Tx0C=2zkv&MmKpe$i(@I4u4(%Y~ zkfC+5AS&W0RV;#q(pG5I!Q|2}Xws0RxHt-~1qVMCs}3&Cx;nTDg5U>;tBaGOi0F(9}L zw41j5eQew96TtrrTxnf@y#>sElHTlU(Ia4J8@RacYVsa%xdRM8>5?HilAoqfDgp0j z^i2gIdL;#2d9Y_EG010qNS#tmY z3ljhU3ljkVnw%H_000McNliru=K~V}2oCM|q%;5k01`<=K~y-)V_+BsqhJ(_0`dR= X1V8`*DUIP(00000NkvXXu0mjfT3g>8 literal 0 HcmV?d00001 diff --git a/Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/unisex_none.png b/Resources/Textures/_EE/Mobs/Customization/masking_helpers.rsi/unisex_none.png new file mode 100644 index 0000000000000000000000000000000000000000..44e0c1358d805be4b575d5a9acf1fd4f0e4ff5bf GIT binary patch literal 1568 zcmV+*2H*LKP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-_Zk|ZY#{pS=u0+Im1ao7~$8~FHskV|hh?XLFx zOhhM91xbphW2 z3Gqp%Q^g- zb7$FmS(FQR@j?=u1PNrUQe;RLmd;ZIyL{V1TW{IwI%Oyx1W6`<5l-ykuEqZy4}r}3 z3K7BkD^{?JdC@>Cin9J81wzQKJc>KO*LZ({SbzjbtuSXeSbaMnTBMiU61RyK2u94| zIIQCYK!~6_!Wa@T;1fxtL|&Pd2yx8dr^0d;7r21}ijfDbXOy-qM?SVu zLLeea5(PCyD!2+E2Gp8{j2x;_Vu&%Os4>S9YmyXFOetwvwOCa&Xw;;tS&P;zIpmmA z)|_+6)fFy+T8$+YExD9ZE0k6sSDdc7Vxw`B7FuknY0Is&+L1mz^w?9^o_p!l4IVPW zh$9Uhd6ZEnO{CHcGtM-1=2>Pnq?(BZi;IDRYZoBagj4pZwpE5Js9sQh5SY1gh6F!1yJrvl z0R34&ZFrefw1;7qqYCn65O#8;`4XbSDXjXX~NO!xA~*MjhPalAhUPsh|^Pu ze*Ha~-LD>a_z7zSh6ux=(Z;%`YDXmBr=~m7>3iAqDlx&@XPiDU{{a0KAVELG*T%nv zTU}7`>gR|600Dz(LqkwWLqi~Na&Km7Y-Iodc$|HaJxIeq9K~PLN<}IT?I7Zip>?t# zD&i2R|084ld5RI=Bjg;0K7Si<6>@l=#1-&?3fz z<9@um_qclp2(21Z&AMYAac;(;P(-OGqIN5i%O6q6Q0b zS~XHkWN1I(;U97QX>!Trs)CVY0d=U596$IU{O;B)O-;H<3+`T*pptK}Qu;1C!qQ}(*YyZd{4`}a(zzaK9ea*XFW7M%b900~e`R7C&) zH2?qr|NsAahD9d;0004WQchCF6XU=)l3@&Et?KmY+L Sjp0=Q0000 zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-_Zk|ZY#{pS=u0+Im1ao7~$8~FHskV|hh?XLFx zOhhM91xbphW2 z3Gqp%Q^g- zb7$FmS(FQR@j?=u1PNrUQe;RLmd;ZIyL{V1TW{IwI%Oyx1W6`<5l-ykuEqZy4}r}3 z3K7BkD^{?JdC@>Cin9J81wzQKJc>KO*LZ({SbzjbtuSXeSbaMnTBMiU61RyK2u94| zIIQCYK!~6_!Wa@T;1fxtL|&Pd2yx8dr^0d;7r21}ijfDbXOy-qM?SVu zLLeea5(PCyD!2+E2Gp8{j2x;_Vu&%Os4>S9YmyXFOetwvwOCa&Xw;;tS&P;zIpmmA z)|_+6)fFy+T8$+YExD9ZE0k6sSDdc7Vxw`B7FuknY0Is&+L1mz^w?9^o_p!l4IVPW zh$9Uhd6ZEnO{CHcGtM-1=2>Pnq?(BZi;IDRYZoBagj4pZwpE5Js9sQh5SY1gh6F!1yJrvl z0R34&ZFrefw1;7qqYCn65O#8;`4XbSDXjXX~NO!xA~*MjhPalAhUPsh|^Pu ze*Ha~-LD>a_z7zSh6ux=(Z;%`YDXmBr=~m7>3iAqDlx&@XPiDU{{a0KAVELG*T%nv zTU}7`>gR|600Dz(LqkwWLqi~Na&Km7Y-Iodc$|HaJxIeq9K~PLN<}IT?I7Zip>?t# zD&i2R|084ld5RI=Bjg;0K7Si<6>@l=#1-&?3fz z<9@um_qclp2(21Z&AMYAac;(;P(-OGqIN5i%O6q6Q0b zS~XHkWN1I(;U97QX>!Trs)CVY0d=U596$IU{O;B)O-;H<3+`T*pptK}Qu;1C!qQ}(*YyZd{4`}a(zzaK9ea*XFW7M%b900~e`R7C&) zH2?qr|NsAahD9d;0004WQchCF6XU=)l3@&Et?KmY+L Sjp0=Q0000p;0$Pm`MUJMNqU_EJc*3MZ|#?OGN|=A{MJX38=W*wcc{A*MDZ^-rTc?@9h1ZeRgt^ z87v5}v2wA(U@$hkK>rZ%>0`Jo&B47CjlYe-m<{Q}A~Yee7OPY#BxoFh)g&nqETTgt z7>w>_Pq?gLuG{$MP423U{Bf2!_1j8S=~KMRcRYT0vpdB>aXUAxf$Qw#^F?s>)D2H= z>~?%nS6|in;ij$2)wlc3yUb;18WO!^N6_r#8t=zN=Z4#LCuTWu)53FZ6f`|K9)A*( zb8zprc_v%p1p~vG`bTx0CZFdnxHY4<$-ZQl&$)}^iZMOR>szJGO#xlqvA_1Xb`E`T zL|CmIzI+O&r@+(T6@FEF9q-kfJf3EO&RbhJQ#75|8gN>m@| zA4OE_2UdA`RXIFcjpZCp|s)OU%TcynK0r*%);by-Hr@w8$$*xkPFQh&#PC$69o z`^$X3*)li0FS|9}hEc>iQaOHOUa>DfIaSg5IDW+k<7eeot<2A=8#MdU?T=v7)=Wo_ zpx9i`K=vX`hGmo+lWS^T=fe9kXeW8DooS>`aC)~#zNgck&AM~EoV2L@%YQn)KJ)6C z&GsT@^c11_tOD_3W$1ymhn?(y4-olI_}10^;AYj;un<19Fo)GyL_0N`?(l{0Cdm?L z*|!evmHP{_w}yO%ZYlGjhBhvd9{Tp!dd}p$$%iL9esjHgVJ>Igu2X|or3$m(C>?<_ zY(GX?nrAKAaV2-hS3i=wbos9mu@Y+y{nS`Cxx2$T~1V&Z~M68w*6&Pe4}^b z%A0-d=gWGUQa$A1sw$Z#YFw7bhJ%57P-RVax$j(fkG8yKCw>~kf5V5x2<0hU*2H)G zwSN5Rpq)z~r+Aap$UD&w*MB~xBlcRVmvsj|^3;Jr*rvR;b?3`QW$M?%s_0c4QX>eZ z?B!E!Gr}7!El#rXe%O9?KWrhb`}Dra;O=sUb8W-c-nPEvsxF%WbG_N0AEoY^-T(C5lry3Cf6txSlefPw z=;~_RCu@)7rY)?xe6nF?_oK_V4wv;5PT&iYet1xLyFa3Id)k_cu6xf*PCUW?_JYTh zUF+GYis;Q+G4J80&EClap0kt9YSzA}^%#v}vfa)WtX?yDXE zc79PxJ}0o=$7%hYgIOVSCOGDIRK3B>9F+d`_VJ3c2(diLz@ z3#IAVM=K^&q+y55I=X(@--VmGdfTLB=XJ_k^~q1qJZ;yeUMV3qK5((1w$rbDpRv8M zJd1P0a(b38#$-q2cSWuT?s}eiWOujw)1sJXyNA^Shmx|JX}HH8l%Soube;Yho!M(2 z5Wx%2Y|6YCG$(H;zdP%qq9_}0?L`qvuJ)g|6IT9o_7jVv1&8bw*Ag z%N|;G-7&{kv=vraEPsUIE?OVgP%&x0`y{KnVds?42~Hhk~9Q!4G1K6f!(4RtOQiPNoDs8-wxk z)+u3;6wzRXNDM0H;CfHh;;^WggIh}D6ZuLm5{m}vRY<5_5GK+~MJzGSd!Ch-jtu~0 zhz7>$WN~seTgSl}aoOP6ASU3jMiY&cgNxt?W4Q_yf~DfAcp@}khbEG7^Q^F5DzSte z;=f=N0*pAgSdB)>CJ?k*EnZ8(D^xKA5{tzm5Xl5G83GoNI!Ug9b&y;=!vHaY;g6_A zDpaXK6>_Wr6Ba5GG#nfb=&`TjlPUT9*YI-nC<}lOf(}*^NO&SaCL@gXP;2HV0+7*w z{?S7n2EN(|A&6R$pb{bT6A`&)##jik=(WExK^13AM=T;Bafl3@q=G` z7$}HAWlEzLAp0##4Jvs<)?2X|G{$ts1_In)ASV25SryPp;O$auH&H0^oQQ z;4qmY29ZuEbS9b1pimer3X4g7V-$|4)Swa# zm?R>eLN;m)%fbf90AgW7odN)(9OT00st{PCP=zTJaU7f>B&@;nwVDsMlNi>({;&oC zphPm6O(L?%^e_^W4c;^gM5MBbW9$`TRFd?+tPPt7>ov0Efv6hHpJWt`?5I#Aeq=N< zj6;oE35zvu3N|bnNkI)KB4T5l0Bb}giiPDd2l>6J(+E~P}3V<+( zM1=lM7-2MFf}v-;%GitWH%`2a24k8G@EehV<^_5o;dL_{<;>7_{>9hmTKtPM0O3UDsJ2CK1#_y}^Jzej_z&jbgude?aT~=?7Q-~b=3etkZQp@TJH8^OQ3l|3X z8;@L=XWUb3z|((}fssICZEv_tFoi` Date: Tue, 14 Jan 2025 23:29:00 -0500 Subject: [PATCH 03/26] spoder --- Content.Client/_EE/Cocoon/CocoonSystem.cs | 4 +- Content.Server/_EE/Cocoon/CocoonerSystem.cs | 6 +- .../_EE/Vampire/BloodSuckerSystem.cs | 12 ++- .../Entities/Body/Mechanisms/vampiric.yml | 22 +++++ .../Entities/Body/Prototypes/arachne.yml | 16 +-- .../Body/Prototypes/vampiricanimal.yml | 43 ++++++++ .../_EE/Entities/Mobs/Species/arachne.yml | 34 +++---- .../_EE/Entities/Structures/Webbing/webs.yml | 93 ++++++++++++++++++ Resources/Prototypes/_EE/Species/arachne.yml | 16 +-- .../Structures/cocoon.rsi/cocoon1.png | Bin 0 -> 669 bytes .../Structures/cocoon.rsi/cocoon2.png | Bin 0 -> 636 bytes .../Structures/cocoon.rsi/cocoon3.png | Bin 0 -> 578 bytes .../Structures/cocoon.rsi/cocoon_large1.png | Bin 0 -> 762 bytes .../Structures/cocoon.rsi/cocoon_large2.png | Bin 0 -> 683 bytes .../Structures/cocoon.rsi/cocoon_large3.png | Bin 0 -> 876 bytes .../Structures/cocoon.rsi/meta.json | 35 +++++++ 16 files changed, 234 insertions(+), 47 deletions(-) create mode 100644 Resources/Prototypes/Nyanotrasen/Entities/Body/Mechanisms/vampiric.yml create mode 100644 Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/vampiricanimal.yml create mode 100644 Resources/Prototypes/_EE/Entities/Structures/Webbing/webs.yml create mode 100644 Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon1.png create mode 100644 Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon2.png create mode 100644 Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon3.png create mode 100644 Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large1.png create mode 100644 Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large2.png create mode 100644 Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large3.png create mode 100644 Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/meta.json diff --git a/Content.Client/_EE/Cocoon/CocoonSystem.cs b/Content.Client/_EE/Cocoon/CocoonSystem.cs index b80ad6dfe15..d3eb4a8205f 100644 --- a/Content.Client/_EE/Cocoon/CocoonSystem.cs +++ b/Content.Client/_EE/Cocoon/CocoonSystem.cs @@ -4,7 +4,7 @@ using Robust.Shared.Containers; using System.Numerics; -namespace Content.Client._EE.Cocoon +namespace Content.Client.Cocoon { public sealed class CocoonSystem : EntitySystem { @@ -21,7 +21,7 @@ private void OnCocEntInserted(EntityUid uid, CocoonComponent component, EntInser return; if (TryComp(args.Entity, out var humanoidAppearance)) // If humanoid, use height and width - cocoonSprite.Scale = new Vector2(1,1); + cocoonSprite.Scale = new Vector2(humanoidAppearance.Width, humanoidAppearance.Height); else if (!TryComp(args.Entity, out var entSprite)) return; else if (entSprite.BaseRSI != null) // Set scale based on sprite scale + sprite dimensions. Ideally we would somehow get a bounding box from the sprite size not including transparent pixels, but FUCK figuring that out. diff --git a/Content.Server/_EE/Cocoon/CocoonerSystem.cs b/Content.Server/_EE/Cocoon/CocoonerSystem.cs index 0d64781afee..db6a4a4d48b 100644 --- a/Content.Server/_EE/Cocoon/CocoonerSystem.cs +++ b/Content.Server/_EE/Cocoon/CocoonerSystem.cs @@ -54,7 +54,7 @@ private void AddVerbs(EntityUid uid, CocoonerComponent component, GetVerbsEvent< private void AddCocoonVerb(EntityUid uid, CocoonerComponent component, GetVerbsEvent args) { - if (!args.CanAccess || !args.CanInteract || !HasComp(args.Target)) + if (!args.CanAccess || !args.CanInteract || !HasComp(args.Target) || args.Target == args.User) return; InnateVerb verb = new() @@ -135,7 +135,7 @@ private void StartCocooning(EntityUid uid, CocoonerComponent component, EntityUi var args = new DoAfterArgs(EntityManager, uid, delay, new CocoonDoAfterEvent(), uid, target: target) { - BreakOnMove = true, + BreakOnMove = true }; _doAfter.TryStartDoAfter(args); @@ -150,7 +150,7 @@ private void StartUnCocooning(EntityUid uid, CocoonerComponent component, Entity var args = new DoAfterArgs(EntityManager, uid, delay, new UnCocoonDoAfterEvent(), uid, target: target) { - BreakOnMove = true, + BreakOnMove = true }; _doAfter.TryStartDoAfter(args); diff --git a/Content.Server/_EE/Vampire/BloodSuckerSystem.cs b/Content.Server/_EE/Vampire/BloodSuckerSystem.cs index e85f211e74b..77fae73bd44 100644 --- a/Content.Server/_EE/Vampire/BloodSuckerSystem.cs +++ b/Content.Server/_EE/Vampire/BloodSuckerSystem.cs @@ -54,8 +54,7 @@ private void AddSuccVerb(EntityUid uid, BloodSuckerComponent component, GetVerbs { victim = cocoon.Victim ?? args.Target; ignoreClothes = cocoon.Victim != null; - } - else if (component.WebRequired) + } else if (component.WebRequired) return; if (!TryComp(victim, out var bloodstream) || args.User == victim || !args.CanAccess) @@ -135,7 +134,7 @@ public void StartSuccDoAfter(EntityUid bloodsucker, EntityUid victim, BloodSucke var args = new DoAfterArgs(EntityManager, bloodsucker, bloodSuckerComponent.Delay, new BloodSuckDoAfterEvent(), bloodsucker, target: victim) { - BreakOnMove = true, + BreakOnMove = false, DistanceThreshold = 2f, NeedHand = false }; @@ -158,10 +157,13 @@ public bool TrySucc(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponen return false; // Does bloodsucker have a stomach? - var stomachList = _bodySystem.GetBodyOrganEntityComps((bloodsucker)); + var stomachList = _bodySystem.GetBodyOrganComponents(bloodsucker); if (stomachList.Count == 0) return false; + if (!_solutionSystem.TryGetSolution(stomachList[0].Comp.Owner, StomachSystem.DefaultSolutionName, out var stomachSolution)) + return false; + // Are we too full? if (_solutionSystem.PercentFull(bloodsucker) >= 1) @@ -183,7 +185,7 @@ public bool TrySucc(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponen return false; var temp = _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSucc); - _stomachSystem.TryTransferSolution(stomachList[0].Owner, temp, stomachList[0]); + _stomachSystem.TryTransferSolution(stomachList[0].Comp.Owner, temp, stomachList[0].Comp); // Add a little pierce DamageSpecifier damage = new(); diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Mechanisms/vampiric.yml b/Resources/Prototypes/Nyanotrasen/Entities/Body/Mechanisms/vampiric.yml new file mode 100644 index 00000000000..e0b08c6d64d --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Entities/Body/Mechanisms/vampiric.yml @@ -0,0 +1,22 @@ +- type: entity + id: OrganVampiricHumanoidStomach + parent: OrganHumanStomach + components: + - type: Metabolizer + # mm yummy + maxReagents: 3 + metabolizerTypes: [Vampiric] + groups: + - id: Food + - id: Drink + +- type: entity + id: OrganVampiricStomach + parent: OrganAnimalStomach + components: + - type: Metabolizer + maxReagents: 3 + metabolizerTypes: [Vampiric] + groups: + - id: Food + - id: Drink diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml b/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml index d8eb35629bf..b5ef64018e6 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml @@ -38,14 +38,14 @@ thorax: part: ThoraxSpider connections: - - left foreleg - - left second leg - - left third leg - - left hind leg - - right foreleg - - right second leg - - right third leg - - right hind leg + - left foreleg + - left second leg + - left third leg + - left hind leg + - right foreleg + - right second leg + - right third leg + - right hind leg left foreleg: part: LeftLegSpider left second leg: diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/vampiricanimal.yml b/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/vampiricanimal.yml new file mode 100644 index 00000000000..c0065ec664e --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/vampiricanimal.yml @@ -0,0 +1,43 @@ +- type: body + id: VampiricAnimal + name: "vampiric animal" + root: torso + slots: + torso: + part: TorsoAnimal + connections: + - legs + organs: + lungs: OrganAnimalLungs + stomach: OrganVampiricStomach + liver: OrganAnimalLiver + heart: OrganAnimalHeart + kidneys: OrganAnimalKidneys + legs: + part: LegsAnimal + connections: + - feet + feet: + part: FeetAnimal + +- type: body + id: VampiricAnimalLarge + name: "large vampiric animal" + root: torso + slots: + torso: + part: TorsoAnimal + connections: + - legs + organs: + lungs: OrganAnimalLungs + stomach: OrganVampiricHumanoidStomach + liver: OrganAnimalLiver + heart: OrganAnimalHeart + kidneys: OrganAnimalKidneys + legs: + part: LegsAnimal + connections: + - feet + feet: + part: FeetAnimal diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Species/arachne.yml b/Resources/Prototypes/_EE/Entities/Mobs/Species/arachne.yml index 54e5fbd3e44..b1fd46966d4 100644 --- a/Resources/Prototypes/_EE/Entities/Mobs/Species/arachne.yml +++ b/Resources/Prototypes/_EE/Entities/Mobs/Species/arachne.yml @@ -13,14 +13,14 @@ state: spider_body - map: [ "enum.HumanoidVisualLayers.Chest" ] color: "#e8b59b" - sprite: /Mobs/Species/Human/parts.rsi + sprite: Mobs/Species/Human/parts.rsi state: torso_m - map: [ "enum.HumanoidVisualLayers.RLeg" ] sprite: _EE/Mobs/Species/arachne.rsi state: spider_body_front - map: [ "enum.HumanoidVisualLayers.Head" ] color: "#e8b59b" - sprite: /Mobs/Species/Human/parts.rsi + sprite: Mobs/Species/Human/parts.rsi state: head_m - map: [ "enum.HumanoidVisualLayers.Eyes" ] color: "#008800" @@ -28,14 +28,14 @@ state: eyes - map: [ "enum.HumanoidVisualLayers.RArm" ] color: "#e8b59b" - sprite: /Mobs/Species/Human/parts.rsi + sprite: Mobs/Species/Human/parts.rsi state: r_arm - map: [ "enum.HumanoidVisualLayers.LArm" ] color: "#e8b59b" - sprite: /Mobs/Species/Human/parts.rsi + sprite: Mobs/Species/Human/parts.rsi state: l_arm - shader: StencilClear - sprite: /Mobs/Species/Human/parts.rsi + sprite: Mobs/Species/Human/parts.rsi state: l_leg - shader: StencilMask map: [ "enum.HumanoidVisualLayers.StencilMask" ] @@ -45,11 +45,11 @@ - map: [ "jumpsuit" ] - map: [ "enum.HumanoidVisualLayers.LHand" ] color: "#e8b59b" - sprite: /Mobs/Species/Human/parts.rsi + sprite: Mobs/Species/Human/parts.rsi state: l_hand - map: [ "enum.HumanoidVisualLayers.RHand" ] color: "#e8b59b" - sprite: /Mobs/Species/Human/parts.rsi + sprite: Mobs/Species/Human/parts.rsi state: r_hand - map: [ "enum.HumanoidVisualLayers.Handcuffs" ] color: "#ffffff" @@ -73,7 +73,7 @@ - map: [ "pocket1" ] - map: [ "pocket2" ] - map: [ "enum.HumanoidVisualLayers.Tail" ] - sprite: _EEMobs/Customization/masking_helpers.rsi + sprite: _EE/Mobs/Customization/masking_helpers.rsi state: none visible: false - map: [ "clownedon" ] # Dynamically generated @@ -134,9 +134,9 @@ fireStackAlternateState: 3 - type: Spider - type: IgnoreSpiderWeb -# - type: FootPrints -# leftBarePrint: "footprint-left-bare-spider" -# rightBarePrint: "footprint-right-bare-spider" + - type: FootPrints + leftBarePrint: "footprint-left-bare-spider" + rightBarePrint: "footprint-right-bare-spider" - type: entity save: false @@ -153,14 +153,14 @@ state: spider_body - map: [ "enum.HumanoidVisualLayers.Chest" ] color: "#e8b59b" - sprite: /Mobs/Species/Human/parts.rsi + sprite: Mobs/Species/Human/parts.rsi state: torso_m - map: [ "enum.HumanoidVisualLayers.RLeg" ] sprite: _EE/Mobs/Species/arachne.rsi state: spider_body_front - map: [ "enum.HumanoidVisualLayers.Head" ] color: "#e8b59b" - sprite: /Mobs/Species/Human/parts.rsi + sprite: Mobs/Species/Human/parts.rsi state: head_m - map: [ "enum.HumanoidVisualLayers.Eyes" ] color: "#008800" @@ -168,14 +168,14 @@ state: eyes - map: [ "enum.HumanoidVisualLayers.RArm" ] color: "#e8b59b" - sprite: /Mobs/Species/Human/parts.rsi + sprite: Mobs/Species/Human/parts.rsi state: r_arm - map: [ "enum.HumanoidVisualLayers.LArm" ] color: "#e8b59b" - sprite: /Mobs/Species/Human/parts.rsi + sprite: Mobs/Species/Human/parts.rsi state: l_arm - shader: StencilClear - sprite: /Mobs/Species/Human/parts.rsi + sprite: Mobs/Species/Human/parts.rsi state: l_leg - shader: StencilMask map: [ "enum.HumanoidVisualLayers.StencilMask" ] @@ -213,7 +213,7 @@ - map: [ "pocket1" ] - map: [ "pocket2" ] - map: [ "enum.HumanoidVisualLayers.Tail" ] - sprite: Mobs/Customization/masking_helpers.rsi + sprite: _EE/Mobs/Customization/masking_helpers.rsi state: none visible: false - type: Inventory diff --git a/Resources/Prototypes/_EE/Entities/Structures/Webbing/webs.yml b/Resources/Prototypes/_EE/Entities/Structures/Webbing/webs.yml new file mode 100644 index 00000000000..c3e020090fd --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Structures/Webbing/webs.yml @@ -0,0 +1,93 @@ +- type: entity + id: CocoonedHumanoid + name: cocooned humanoid + description: Unlucky. + placement: + mode: SnapgridCenter + snap: + - Wall + components: + - type: Sprite + layers: + - sprite: Nyanotrasen/Structures/cocoon.rsi + state: cocoon_large1 + map: [ "enum.DamageStateVisualLayers.Base" ] + - type: RandomSprite + available: + - enum.DamageStateVisualLayers.Base: + cocoon_large1: "" + - enum.DamageStateVisualLayers.Base: #your guess for why randomsprite requires an arbitrary layer is as good as mine friend + cocoon_large2: "" + - enum.DamageStateVisualLayers.Base: + cocoon_large3: "" + - type: Cocoon + - type: Clickable + - type: InteractionOutline + - type: Transform + noRot: true + - type: Damageable + damageModifierSet: Web + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 40 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.25,-0.4,0.25,0.1" + density: 20 + mask: + - SmallMobMask + layer: + - SmallMobLayer + - type: Physics + bodyType: Dynamic + - type: Pullable + - type: AntiRottingContainer + - type: ItemSlots + slots: + body_slot: + name: Body + locked: true + ejectOnBreak: true + - type: Butcherable + butcheringType: Knife + butcherDelay: 12 + spawned: + - id: MaterialWebSilk1 + amount: 1 + prob: 0.5 #This doesn't cost hunger so should at least make it not worth it time-wise + - type: Appearance + - type: ContainerContainer + containers: + body_slot: !type:ContainerSlot + +- type: entity + id: CocoonSmall + parent: CocoonedHumanoid + name: cocoon + description: What could be inside...? + placement: + mode: SnapgridCenter + snap: + - Wall + components: + - type: Sprite + layers: + - sprite: Nyanotrasen/Structures/cocoon.rsi + state: cocoon1 + map: [ "enum.DamageStateVisualLayers.Base" ] + - type: RandomSprite + available: + - enum.DamageStateVisualLayers.Base: + cocoon1: "" + - enum.DamageStateVisualLayers.Base: #your guess for why randomsprite requires an arbitrary layer is as good as mine friend + cocoon2: "" + - enum.DamageStateVisualLayers.Base: + cocoon3: "" diff --git a/Resources/Prototypes/_EE/Species/arachne.yml b/Resources/Prototypes/_EE/Species/arachne.yml index 08be5d27728..57b82e88bae 100644 --- a/Resources/Prototypes/_EE/Species/arachne.yml +++ b/Resources/Prototypes/_EE/Species/arachne.yml @@ -30,25 +30,17 @@ Chest: points: 1 required: false - RightArm: + Arms: points: 2 required: false - RightHand: - points: 3 - required: false - LeftArm: - points: 2 - required: false - LeftHand: - points: 3 + Undershirt: # DeltaV + points: 1 required: false - - type: speciesBaseSprites id: MobArachneSprites sprites: Head: MobHumanHead - Face: MobHumanoidAnyMarking HeadSide: MobHumanoidAnyMarking Hair: MobHumanoidAnyMarking FacialHair: MobHumanoidAnyMarking @@ -63,5 +55,5 @@ - type: humanoidBaseSprite id: MobArachneEyes baseSprite: - sprite: Mobs/Species/eyes.rsi + sprite: _EE/Mobs/Species/eyes.rsi state: eyes diff --git a/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon1.png b/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon1.png new file mode 100644 index 0000000000000000000000000000000000000000..27741fdf314bc38be7153151d603479000af1891 GIT binary patch literal 669 zcmV;O0%HA%P)$5Dx(m zFBXfsFs^ZhFvIKhs_Q@?a2Eu|Znw+%d={V2CxgL2(&@BRt5s77QvgGJv)QP)!{Lxf zBqH5zS3;qX0suChPIdoDARG?Ma5&VIZq5}t7z~=4e3$?qrcx<&lF#R5GMOk0#n$Wf zbgvNx%x1I6<#LhTZYQJB=)MNvY>Qb6p90{%P$;MnB8HP#EGF%CTX=>j_YedE$8-R| z2pY9PD*b+6(|S1pqs>SHF&0TClhWyQ6o&J|;UM$*{N4f71zSRDY#+4%AZuXAG5}6) zJ*{FSF&>X~3xL8MAVy2#m^3I#?&oqjg$5#%$!M*-lmLq%x>zjq8dr$n%mCybVgTLx zUR_f8)C2?Ph&LJyX|-C`y5LqQR|<#N5hY3%&StYJXt<{%0O37mT984J0?BUyP@joE zOaO?F549B$#R;MmAA^~AnE_;<*&=3=1DK@06q*z%=`4(1e*jw4~ z0qlJMWovU6H!CGJl-MY-xwmdtq%iY)ns=JT%y?aMo6Y-_-gBJS`Tw5(^PJ}DNTn6v)$^dz}l z?&{uG0e*DwrC2OVzu#ADv6;^I`F#40Q3}HmU~mHGDA`>A1U8Z_U5_|(ZouJi__HaQ zb4ntSh&q9ItyYt6w|oCZ)ai881#Y-_Jg%Y$7#{#)v6!9+#DQ$JTE_40cff%7Zs&#L z)@(La1XswMBT4plyIm@kirRiH^P2&PUpCc0o8Q&ftnh~bj4)&Ervm)TumCIo3*Z}` WA1sKIggnat0000>)WwzxBKr~01&TMs}c%@WV_wUYPFI?BEi)4t02Yzh&P)}+3)w-zg#X- zDwPz3@mqWv#0bC=C*w>eBcstsa=Dy%JRWspHk*mt?Us7It}P&@5XKH5PW1czd*+CH zy=I<#amf@8*aR#6tkGuT&~3hV6jRB0QN)BpQv%Znx93ryd@e$n4R$MNZwy{|3K8G+z z!Wb@C4gm4&)`v%71mO4kWiS|M;ZcBOY1xfC6eHr)fzRi=uS=y;5BGiuKv5kI2Xz3D zbULj^5ex=jy*HoFRS*~g7kH2Lwg7s)9`;=ujfVCSW>Y>rs(-WDs2hPmKqp|B26zX=cKp8o0}g-#@aF*j10gEyIQQql Q8~^|S07*qoM6N<$f*=3`Hvj+t literal 0 HcmV?d00001 diff --git a/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large1.png b/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large1.png new file mode 100644 index 0000000000000000000000000000000000000000..f9431f6428586fe569344878961bd645cbc04fc6 GIT binary patch literal 762 zcmVgc z)HGVt5GrUW(MCfaUs*`R6?PUu8&3| zNvG3tb#*1>a@o1Oyxf|EOMu{L0LW@nhDS$7QYw{P@YQN1KA%r^cX!o}?e_MT;npOS z0IYMloFtP;d3$?vgMWN{xLH0wKdZ(L0YI@wA`ywlP)iTC$+wedl~_5y~WPfkvBj3y>__7w^Rr`>L^ z5zz`*DNQVxW%cy*B;jyavm+Di%jHt5z#cw`quGZf5((9|PBO$gJv}9kQ>j#T)_MSj znM}ql8BVj=Oq~EE3y3gB=JUBr#MYRT2ni7n!3I&PNX3w1u}F_;pC|#GC@tUs6Lhgy zXaidIcHUNUn{!$Y^}?1i+)CY#N=3DoO#J%UXS&qe~DNc>iKw1&f>5L*PT;*8~QGffs!} zpU=Pki~!)>Zr7AbC3$_n-??}$BvKPl@Or&&PN$QpR;%WCJR0t~kVr)!dh+Mb%Vi;e0@UO25G7E>wo((o??RzquGg!nR4V3jxrFbX&*%3O z0E81G`|WlU5)_17DiwjiTW>rbi}%=(&*ww%*=%N(%jNq**lxEagrpwNU$2*_ffB3L z${IWs0l-J2k@(Mp0$hEk3tY;H0N}k|Po8sfE##*a31Y2Q6cTGIE(O#1Pj;9&toXiW$VheODDlgT8zK?E?T*O80l5Ya3g z4hJEF1z2KRP8L9d0(`w*ixt?Qz^Fn+hf<~lIGK9w2T~;8?RMdb)e4s!I1vDV(_;Z@ zaAJsPK?p0bYO~p7OCV?~nE~2@bb^MDJU|djc%Q%;i;ZYaz@K~`sb}CY@i-+99Y(s8 zAhX?W!`+Zni39-V>bIfvJK>}Bq&oirjJ71z@AtXHst`+{)9H8sBQF4W&yONKK#(DT zyoWmEg6Am1XCX43PGd<}SpWz>hyvPj6oG^YkErDOS?<#jTvI6!Y&B08jIW6P@f20a z0#hxX%$l3vJF)B8X%5)#dD~4${QyPKZkme+ R_X7X`002ovPDHLkV1mDMGcW)E literal 0 HcmV?d00001 diff --git a/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large3.png b/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large3.png new file mode 100644 index 0000000000000000000000000000000000000000..9a033961ffa27e1796d98c10f6fc9d563f13066a GIT binary patch literal 876 zcmV-y1C#uTP)P6p9*9R5b`t4M~gH+uwv|vr7wIu9v%9!kbKXc6WH6-}`4~`Dy;KodM1O zXMq0~pwVbJn!mrlo5#n;AAbb^VFc^-x=E+g=JoZ}j(k4v%;$5{ZnsYYISByqTrOv7 zwVJuOxG?MW+Hj9uUtgQaWWv-r1tK&6;zS*dMolahvjAM5pPy|e7K??sy1FuzN`)+h z4k{FY#EEjXTG^3ICM^VmdolqKFsu)og-`&AM8Z1e${_WsJ@>Nhc5BBe_9ejW?XBZB zm`y#x5`1}ivC#uTHvG^27y#ncYSqq_b|M4;| za|~gkCEcuJOs7*jPO%RF_xJZssZ{bB3Nbl}=HBV1Z zwiJ4&5-<=Js4E;0Z#J9Wx8hhy0swb+ced-*Ob8%O#Hm!ut2qXwj8m{&E;Dt2K-~3Z z-|aHx9D)b{5EUJdai!im;UbZUd3$@a5Tu<>M;N1I7(2#YZ_f>Sf#zjBr>G0;d{&+S z01k;V?-3skhjz|8t_T9m z+}|fW$GGwZB@4Y?FOY=*0ClCCHQ-*^ct8vPUUAI}K#JNiLu*@g_>hbjTa zp9$BgLl%fe;>v~^j7|qqe@X^I;+0IbvLu-NH#yC###c+Y{tIbhlW zM6IJ*< Date: Wed, 15 Jan 2025 21:59:28 -0500 Subject: [PATCH 04/26] spoder --- Content.Client/_EE/Cocoon/CocoonSystem.cs | 2 +- Content.Server/_EE/Cocoon/CocoonerSystem.cs | 2 +- .../_EE/Vampire/BloodSuckedComponent.cs | 4 ++-- .../_EE/Vampire/BloodSuckerComponent.cs | 6 +++--- .../_EE/Vampire/BloodSuckerSystem.cs | 11 +++++++---- .../BloodSuckerGlandInjectorSystem.cs | 3 ++- .../en-US/_EE/abilities/bloodsucker.ftl | 19 +++++++++++++++++++ 7 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 Resources/Locale/en-US/_EE/abilities/bloodsucker.ftl diff --git a/Content.Client/_EE/Cocoon/CocoonSystem.cs b/Content.Client/_EE/Cocoon/CocoonSystem.cs index d3eb4a8205f..f6b66a4b395 100644 --- a/Content.Client/_EE/Cocoon/CocoonSystem.cs +++ b/Content.Client/_EE/Cocoon/CocoonSystem.cs @@ -21,7 +21,7 @@ private void OnCocEntInserted(EntityUid uid, CocoonComponent component, EntInser return; if (TryComp(args.Entity, out var humanoidAppearance)) // If humanoid, use height and width - cocoonSprite.Scale = new Vector2(humanoidAppearance.Width, humanoidAppearance.Height); + cocoonSprite.Scale = new Vector2(1,1); else if (!TryComp(args.Entity, out var entSprite)) return; else if (entSprite.BaseRSI != null) // Set scale based on sprite scale + sprite dimensions. Ideally we would somehow get a bounding box from the sprite size not including transparent pixels, but FUCK figuring that out. diff --git a/Content.Server/_EE/Cocoon/CocoonerSystem.cs b/Content.Server/_EE/Cocoon/CocoonerSystem.cs index db6a4a4d48b..9a10d9f5a79 100644 --- a/Content.Server/_EE/Cocoon/CocoonerSystem.cs +++ b/Content.Server/_EE/Cocoon/CocoonerSystem.cs @@ -1,4 +1,4 @@ -using Content.Shared.Cocoon; +using Content.Shared.Cocoon; using Content.Shared.IdentityManagement; using Content.Shared.Verbs; using Content.Shared.DoAfter; diff --git a/Content.Server/_EE/Vampire/BloodSuckedComponent.cs b/Content.Server/_EE/Vampire/BloodSuckedComponent.cs index d7e402cd98a..df0eb4e3d65 100644 --- a/Content.Server/_EE/Vampire/BloodSuckedComponent.cs +++ b/Content.Server/_EE/Vampire/BloodSuckedComponent.cs @@ -1,7 +1,7 @@ -namespace Content.Server.Vampiric +namespace Content.Server.Vampire { /// - /// For entities who have been succed. + /// For entities who have been sucked. /// [RegisterComponent] public sealed partial class BloodSuckedComponent : Component diff --git a/Content.Server/_EE/Vampire/BloodSuckerComponent.cs b/Content.Server/_EE/Vampire/BloodSuckerComponent.cs index f5619d1cb49..65c0f33cce4 100644 --- a/Content.Server/_EE/Vampire/BloodSuckerComponent.cs +++ b/Content.Server/_EE/Vampire/BloodSuckerComponent.cs @@ -1,16 +1,16 @@ -namespace Content.Server.Vampiric +namespace Content.Server.Vampire { [RegisterComponent] public sealed partial class BloodSuckerComponent : Component { /// - /// How much to succ each time we succ. + /// How much to suck each time we suck. /// [DataField("unitsToSucc")] public float UnitsToSucc = 20f; /// - /// The time (in seconds) that it takes to succ an entity. + /// The time (in seconds) that it takes to suck an entity. /// [DataField, ViewVariables(VVAccess.ReadWrite)] public TimeSpan Delay = TimeSpan.FromSeconds(4); diff --git a/Content.Server/_EE/Vampire/BloodSuckerSystem.cs b/Content.Server/_EE/Vampire/BloodSuckerSystem.cs index 77fae73bd44..e3b18204351 100644 --- a/Content.Server/_EE/Vampire/BloodSuckerSystem.cs +++ b/Content.Server/_EE/Vampire/BloodSuckerSystem.cs @@ -1,3 +1,4 @@ +using System.Linq; using Content.Shared.Verbs; using Content.Shared.Damage; using Content.Shared.DoAfter; @@ -19,7 +20,7 @@ using Robust.Shared.Audio.Systems; using Robust.Shared.Utility; -namespace Content.Server.Vampiric +namespace Content.Server.Vampire { public sealed class BloodSuckerSystem : EntitySystem { @@ -157,11 +158,13 @@ public bool TrySucc(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponen return false; // Does bloodsucker have a stomach? - var stomachList = _bodySystem.GetBodyOrganComponents(bloodsucker); + var stomachList = _bodySystem.GetBodyOrganEntityComps(bloodsucker); if (stomachList.Count == 0) return false; - if (!_solutionSystem.TryGetSolution(stomachList[0].Comp.Owner, StomachSystem.DefaultSolutionName, out var stomachSolution)) + var stomach = stomachList.FirstOrDefault(); // DeltaV + + if (!_solutionSystem.TryGetSolution(bloodsucker, StomachSystem.DefaultSolutionName, out var stomachSolution)) return false; // Are we too full? @@ -185,7 +188,7 @@ public bool TrySucc(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponen return false; var temp = _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSucc); - _stomachSystem.TryTransferSolution(stomachList[0].Comp.Owner, temp, stomachList[0].Comp); + _stomachSystem.TryTransferSolution(bloodsucker, temp, stomach); // DeltaV // Add a little pierce DamageSpecifier damage = new(); diff --git a/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs b/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs index d2a92f24be6..3c24acbded2 100644 --- a/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs +++ b/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs @@ -1,7 +1,8 @@ using Content.Server.Popups; +using Content.Server.Vampiric; using Content.Shared.Interaction; -namespace Content.Server.Vampiric +namespace Content.Server.Vampire { public sealed class BloodSuckerGlandInjectorSystem : EntitySystem { diff --git a/Resources/Locale/en-US/_EE/abilities/bloodsucker.ftl b/Resources/Locale/en-US/_EE/abilities/bloodsucker.ftl new file mode 100644 index 00000000000..c8aa0ed8542 --- /dev/null +++ b/Resources/Locale/en-US/_EE/abilities/bloodsucker.ftl @@ -0,0 +1,19 @@ +action-name-suck-blood = Suck Blood +action-description-suck-blood = Suck the blood of the victim in your hand. + +bloodsucker-fail-helmet = You'd need to remove {THE($helmet)}. +bloodsucker-fail-mask = You'd need to remove your mask! + +bloodsucker-not-blood = {$target} doesn't have delicious, nourishing blood. +bloodsucker-fail-no-blood = {$target} has no blood in { POSS-ADJ($target) } body. +bloodsucker-fail-no-blood-bloodsucked = {$target} has been sucked dry. + +bloodsucker-blood-sucked = You suck some blood from {$target}. +bloodsucker-doafter-start = You try to suck blood from {$target}. + +bloodsucker-doafter-start-victim = {CAPITALIZE(THE($sucker))} is trying to bite your neck! +bloodsucker-blood-sucked-victim = {CAPITALIZE(THE($sucker))} sucks some of your blood! + +bloodsucked-health-examine = [color=red]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } bite marks on { POSS-ADJ($target) } neck.[/color] + +bloodsucker-glands-throb = The glands behind your fangs feel a bit sore. From 5c995eb2ce485dd7b9867cd02003a336504e26f8 Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Mon, 20 Jan 2025 13:34:53 -0500 Subject: [PATCH 05/26] arachne real --- .../Mobs/Customization/Markings/arachnid.yml | 30 ++++++++--------- .../Entities/Body/Parts/spider.yml | 1 + .../Entities/Body/Prototypes/arachne.yml | 33 ++++++++++--------- .../_EE/Entities/Mobs/Species/arachne.yml | 3 ++ Resources/Prototypes/_EE/Species/arachne.yml | 3 -- 5 files changed, 36 insertions(+), 34 deletions(-) diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/arachnid.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/arachnid.yml index f4c446df5b7..f89e8f62467 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/arachnid.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/arachnid.yml @@ -122,7 +122,7 @@ id: ArachnidTorsoStripes bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: stripes @@ -135,7 +135,7 @@ id: ArachnidTorsoSlashes bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: slashes @@ -148,7 +148,7 @@ id: ArachnidTorsoX bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: x @@ -161,7 +161,7 @@ id: ArachnidTorsoCross bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: cross @@ -174,7 +174,7 @@ id: ArachnidTorsoHeart bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: heart @@ -187,7 +187,7 @@ id: ArachnidTorsoHourglass bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: hourglass @@ -200,7 +200,7 @@ id: ArachnidTorsoNailAndHammer bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: nail-and-hammer @@ -213,7 +213,7 @@ id: ArachnidTorsoStar bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: star @@ -226,7 +226,7 @@ id: ArachnidTorsoArrows bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: arrows @@ -239,7 +239,7 @@ id: ArachnidTorsoCore bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: core @@ -252,7 +252,7 @@ id: ArachnidTorsoFiddleback bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: fiddleback @@ -265,7 +265,7 @@ id: ArachnidTorsoSkull bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: skull @@ -278,7 +278,7 @@ id: ArachnidTorsoTarget bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: target @@ -292,7 +292,7 @@ id: ArachnidRArmStripes bodyPart: RArm markingCategory: Arms - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/arms.rsi state: stripes_right @@ -305,7 +305,7 @@ id: ArachnidLArmStripes bodyPart: LArm markingCategory: Arms - speciesRestriction: [Arachnid] + speciesRestriction: [Arachnid, Arachne]] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/arms.rsi state: stripes_left diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml b/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml index f642c8f27c4..1891cf0b065 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml @@ -36,6 +36,7 @@ sprite: Mobs/Species/Moth/parts.rsi state: "torso_m" - type: BodyPart #"Other" type + slotId: thorax - type: Extractable juiceSolution: reagents: diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml b/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml index b5ef64018e6..cbcd4e97856 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml @@ -38,27 +38,28 @@ thorax: part: ThoraxSpider connections: - - left foreleg - - left second leg - - left third leg - - left hind leg - - right foreleg - - right second leg - - right third leg - - right hind leg - left foreleg: + # The slots needs to start with (symmetry) (part) or they're not gonna be registered + - left leg (fore) + - left leg (second) + - left leg (third) + - left leg (hind) + - right leg (fore) + - right leg (second) + - right leg (third) + - right leg (hind) + left leg (fore): part: LeftLegSpider - left second leg: + left leg (second): part: LeftLegSpider - left third leg: + left leg (third): part: LeftLegSpider - left hind leg: + left leg (hind): part: LeftLegSpider - right foreleg: + right leg (fore): part: RightLegSpider - right second leg: + right leg (second): part: RightLegSpider - right third leg: + right leg (third): part: RightLegSpider - right hind leg: + right leg (hind): part: RightLegSpider diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Species/arachne.yml b/Resources/Prototypes/_EE/Entities/Mobs/Species/arachne.yml index b1fd46966d4..8dd6e62f1bc 100644 --- a/Resources/Prototypes/_EE/Entities/Mobs/Species/arachne.yml +++ b/Resources/Prototypes/_EE/Entities/Mobs/Species/arachne.yml @@ -65,6 +65,7 @@ - map: [ "belt" ] - map: [ "neck" ] - map: [ "back" ] + - map: [ "enum.HumanoidVisualLayers.FacialHair"] - map: [ "enum.HumanoidVisualLayers.Hair" ] state: bald sprite: Mobs/Customization/human_hair.rsi @@ -104,6 +105,7 @@ - type: Tag tags: - CanPilot + - FootstepSound - DoorBumpOpener - type: Bloodstream bloodReagent: DemonsBlood @@ -205,6 +207,7 @@ - map: [ "belt" ] - map: [ "neck" ] - map: [ "back" ] + - map: [ "enum.HumanoidVisualLayers.FacialHair" ] - map: [ "enum.HumanoidVisualLayers.Hair" ] state: bald sprite: Mobs/Customization/human_hair.rsi diff --git a/Resources/Prototypes/_EE/Species/arachne.yml b/Resources/Prototypes/_EE/Species/arachne.yml index 57b82e88bae..f74cba57dfe 100644 --- a/Resources/Prototypes/_EE/Species/arachne.yml +++ b/Resources/Prototypes/_EE/Species/arachne.yml @@ -8,9 +8,6 @@ markingLimits: MobArachneMarkingLimits dollPrototype: MobArachneDummy skinColoration: HumanToned - femaleFirstNames: names_arachnid_first - sexes: - - Female - type: markingPoints id: MobArachneMarkingLimits From 433f86e7455a936b5104b01994fbd3833b92fc35 Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Thu, 23 Jan 2025 08:54:12 -0500 Subject: [PATCH 06/26] aaaaaaaaa --- .../_EE/metabolism/metabolizer-types.ftl | 1 + .../Mobs/Customization/Markings/arachnid.yml | 30 +++++++++---------- .../Mobs/Customization/Markings/ears.yml | 2 +- .../Mobs/Customization/Markings/gauze.yml | 22 +++++++------- .../Customization/Markings/human_noses.yml | 10 +++---- .../Mobs/Customization/Markings/scars.yml | 10 +++---- .../Mobs/Customization/Markings/tattoos.yml | 16 +++++----- .../Entities/Body/Parts/spider.yml | 6 +++- Resources/Prototypes/Reagents/biological.yml | 27 +++++++++++++++++ .../Mobs/Customization/Markings/makeup.yml | 2 +- .../_EE/Chemistry/metabolizer_types.yml | 3 ++ 11 files changed, 82 insertions(+), 47 deletions(-) create mode 100644 Resources/Locale/en-US/_EE/metabolism/metabolizer-types.ftl create mode 100644 Resources/Prototypes/_EE/Chemistry/metabolizer_types.yml diff --git a/Resources/Locale/en-US/_EE/metabolism/metabolizer-types.ftl b/Resources/Locale/en-US/_EE/metabolism/metabolizer-types.ftl new file mode 100644 index 00000000000..f06cdfbeb2b --- /dev/null +++ b/Resources/Locale/en-US/_EE/metabolism/metabolizer-types.ftl @@ -0,0 +1 @@ +metabolizer-type-vampiric = Vampiric diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/arachnid.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/arachnid.yml index f89e8f62467..0d64e334be5 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/arachnid.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/arachnid.yml @@ -122,7 +122,7 @@ id: ArachnidTorsoStripes bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: stripes @@ -135,7 +135,7 @@ id: ArachnidTorsoSlashes bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: slashes @@ -148,7 +148,7 @@ id: ArachnidTorsoX bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: x @@ -161,7 +161,7 @@ id: ArachnidTorsoCross bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: cross @@ -174,7 +174,7 @@ id: ArachnidTorsoHeart bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: heart @@ -187,7 +187,7 @@ id: ArachnidTorsoHourglass bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: hourglass @@ -200,7 +200,7 @@ id: ArachnidTorsoNailAndHammer bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: nail-and-hammer @@ -213,7 +213,7 @@ id: ArachnidTorsoStar bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: star @@ -226,7 +226,7 @@ id: ArachnidTorsoArrows bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: arrows @@ -239,7 +239,7 @@ id: ArachnidTorsoCore bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: core @@ -252,7 +252,7 @@ id: ArachnidTorsoFiddleback bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: fiddleback @@ -265,7 +265,7 @@ id: ArachnidTorsoSkull bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: skull @@ -278,7 +278,7 @@ id: ArachnidTorsoTarget bodyPart: Chest markingCategory: Chest - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/chest.rsi state: target @@ -292,7 +292,7 @@ id: ArachnidRArmStripes bodyPart: RArm markingCategory: Arms - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/arms.rsi state: stripes_right @@ -305,7 +305,7 @@ id: ArachnidLArmStripes bodyPart: LArm markingCategory: Arms - speciesRestriction: [Arachnid, Arachne]] # EE Arachne + speciesRestriction: [Arachnid, Arachne] # EE Arachne sprites: - sprite: Mobs/Customization/Arachnid/arms.rsi state: stripes_left diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/ears.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/ears.yml index 6e350880329..143e86a1be0 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/ears.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/ears.yml @@ -2,7 +2,7 @@ id: HumanLongEars bodyPart: HeadTop markingCategory: HeadTop - speciesRestriction: [Human, Dwarf] + speciesRestriction: [Human, Dwarf, Arachne] # DeltaV Arachne forcedColoring: true followSkinColor: true sprites: diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/gauze.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/gauze.yml index 540d098e505..71d5508e2c9 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/gauze.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/gauze.yml @@ -2,7 +2,7 @@ id: GauzeLefteyePatch bodyPart: Eyes markingCategory: Overlay - speciesRestriction: [Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, Rodentia] # Delta V - Felinid, Oni, Vulpkanin, Rodentia + speciesRestriction: [Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, Rodentia, Arachne] # Delta V - Felinid, Oni, Vulpkanin, Rodentia # EE - Arachne coloring: default: type: @@ -16,7 +16,7 @@ id: GauzeLefteyePad bodyPart: Eyes markingCategory: Overlay - speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, Felinid, Oni, Vulpkanin, Rodentia] # Delta V - Felinid, Oni, Vulpkanin, Rodentia + speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, Felinid, Oni, Vulpkanin, Rodentia, Arachne] # Delta V - Felinid, Oni, Vulpkanin, Rodentia # EE - Arachne coloring: default: type: @@ -30,7 +30,7 @@ id: GauzeRighteyePatch bodyPart: Eyes markingCategory: Overlay - speciesRestriction: [Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, Rodentia] # Delta V - Felinid, Oni, Vulpkanin, Rodentia + speciesRestriction: [Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, Rodentia, Arachne] # Delta V - Felinid, Oni, Vulpkanin, Rodentia # EE - Arachne coloring: default: type: @@ -44,7 +44,7 @@ id: GauzeRighteyePad bodyPart: Eyes markingCategory: Overlay - speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, Felinid, Oni, Vulpkanin, Rodentia] # Delta V - Felinid, Oni, Vulpkanin, Rodentia + speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, Felinid, Oni, Vulpkanin, Rodentia, Arachne] # Delta V - Felinid, Oni, Vulpkanin, Rodentia # EE - Arachne coloring: default: type: @@ -58,7 +58,7 @@ id: GauzeBlindfold bodyPart: Eyes markingCategory: Overlay - speciesRestriction: [Dwarf, Human, Arachnid, Felinid, Oni, Harpy, Vulpkanin, Rodentia] # Delta V - Felinid, Oni, Harpy, Vulpkanin, Rodentia + speciesRestriction: [Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, Rodentia, Arachne] # Delta V - Felinid, Oni, Vulpkanin, Rodentia # EE - Arachne coloring: default: type: @@ -72,7 +72,7 @@ id: GauzeShoulder bodyPart: Chest markingCategory: Overlay - speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, Felinid, Oni, Vulpkanin, Rodentia] # Delta V - Felinid, Oni, Vulpkanin, Rodentia + speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, Felinid, Oni, Vulpkanin, Rodentia, Arachne] # Delta V - Felinid, Oni, Vulpkanin, Rodentia # EE - Arachne coloring: default: type: @@ -86,7 +86,7 @@ id: GauzeStomach bodyPart: Chest markingCategory: Overlay - speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, Felinid, Oni, Vulpkanin, Rodentia] # Delta V - Felinid, Oni, Vulpkanin, Rodentia + speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, Felinid, Oni, Vulpkanin, Rodentia, Arachne] # Delta V - Felinid, Oni, Vulpkanin, Rodentia # EE - Arachne coloring: default: type: @@ -100,7 +100,7 @@ id: GauzeUpperArmRight bodyPart: RArm markingCategory: Overlay - speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, SlimePerson, Felinid, Oni, Vulpkanin, Rodentia] # Delta V - Felinid, Oni, Vulpkanin, Rodentia + speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, Felinid, Oni, Vulpkanin, Rodentia, Arachne] # Delta V - Felinid, Oni, Vulpkanin, Rodentia # EE - Arachne coloring: default: type: @@ -114,7 +114,7 @@ id: GauzeLowerArmRight bodyPart: RArm, RHand markingCategory: Overlay - speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, SlimePerson, Felinid, Oni, Vulpkanin, Rodentia] # Delta V - Felinid, Oni, Vulpkanin, Rodentia + speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, SlimePerson, Felinid, Oni, Vulpkanin, Rodentia, Arachne ] # Delta V - Felinid, Oni, Vulpkanin, Rodentia #EE - Arachne coloring: default: type: @@ -128,7 +128,7 @@ id: GauzeLeftArm bodyPart: LArm, LHand markingCategory: Overlay - speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, Felinid, Oni, Vulpkanin, Rodentia] # Delta V - Felinid, Oni, Vulpkanin, Rodentia + speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, Felinid, Oni, Vulpkanin, Rodentia, Arachne] # Delta V - Felinid, Oni, Vulpkanin, Rodentia # EE - Arachne coloring: default: type: @@ -142,7 +142,7 @@ id: GauzeLowerLegLeft bodyPart: LFoot markingCategory: Overlay - speciesRestriction: [Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, Rodentia] # Delta V - Felinid, Oni, Vulpkanin, Rodentia + speciesRestriction: [Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, Rodentia, Arachne] # Delta V - Felinid, Oni, Vulpkanin, Rodentia # EE - Arachne coloring: default: type: diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/human_noses.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/human_noses.yml index 19373e79d8d..12bdf9695fe 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/human_noses.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/human_noses.yml @@ -4,7 +4,7 @@ markingCategory: Snout followSkinColor: true forcedColoring: true - speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy] #Einstein Engines - Felinid, Oni, Harpy + speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy, Arachne] # EE - Felinid, Oni, Harpy, Arachne sprites: - sprite: Mobs/Customization/human_noses.rsi state: schnozz @@ -15,7 +15,7 @@ markingCategory: Snout followSkinColor: true forcedColoring: true - speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy] #Einstein Engines - Felinid, Oni, Harpy + speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy, Arachne] # EE - Felinid, Oni, Harpy, Arachne sprites: - sprite: Mobs/Customization/human_noses.rsi state: nubby @@ -26,7 +26,7 @@ markingCategory: Snout followSkinColor: true forcedColoring: true - speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy] #Einstein Engines - Felinid, Oni, Harpy + speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy, Arachne] # EE - Felinid, Oni, Harpy, Arachne sprites: - sprite: Mobs/Customization/human_noses.rsi state: droop @@ -37,7 +37,7 @@ markingCategory: Snout followSkinColor: true forcedColoring: true - speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy] #Einstein Engines - Felinid, Oni, Harpy + speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy, Arachne] # EE - Felinid, Oni, Harpy, Arachne sprites: - sprite: Mobs/Customization/human_noses.rsi state: blob @@ -48,7 +48,7 @@ markingCategory: Snout followSkinColor: true forcedColoring: true - speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy] #Einstein Engines - Felinid, Oni, Harpy + speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy, Arachne] # EE - Felinid, Oni, Harpy, Arachne sprites: - sprite: Mobs/Customization/human_noses.rsi state: uppie diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/scars.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/scars.yml index 822be2893c4..503c229671c 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/scars.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/scars.yml @@ -2,7 +2,7 @@ id: ScarEyeRight bodyPart: Head markingCategory: Head - speciesRestriction: [Human, Dwarf, Felinid, Harpy, Oni, Rodentia] # Delta V - Felinid, Oni, Harpy, Rodentia + speciesRestriction: [Human, Dwarf, Felinid, Harpy, Oni, Rodentia, Arachne] # Delta V - Felinid, Oni, Harpy, Rodentia # EE - Arachne followSkinColor: true sprites: - sprite: Mobs/Customization/scars.rsi @@ -12,7 +12,7 @@ id: ScarEyeLeft bodyPart: Head markingCategory: Head - speciesRestriction: [Human, Dwarf, Felinid, Harpy, Oni, Rodentia] # Delta V - Felinid, Oni, Harpy, Rodentia + speciesRestriction: [Human, Dwarf, Felinid, Harpy, Oni, Rodentia, Arachne] # Delta V - Felinid, Oni, Harpy, Rodentia # EE - Arachne followSkinColor: true sprites: - sprite: Mobs/Customization/scars.rsi @@ -22,7 +22,7 @@ id: ScarTopSurgeryShort bodyPart: Chest markingCategory: Chest - speciesRestriction: [Human, Dwarf, Felinid, Oni] #Einstein Engines - Felinid, Oni + speciesRestriction: [Human, Dwarf, Felinid, Oni, Arachne] # EE - Felinid, Oni, Arachne sexRestriction: [Male] followSkinColor: true sprites: @@ -33,7 +33,7 @@ id: ScarTopSurgeryLong bodyPart: Chest markingCategory: Chest - speciesRestriction: [Human, Dwarf, Felinid, Oni] #Einstein Engines - Felinid, Oni + speciesRestriction: [Human, Dwarf, Felinid, Oni, Arachne] # EE - Felinid, Oni, Arachne sexRestriction: [Male] followSkinColor: true sprites: @@ -44,7 +44,7 @@ id: ScarChest bodyPart: Chest markingCategory: Chest - speciesRestriction: [Human, Dwarf, Felinid, Oni] #Einstein Engines - Felinid, Oni + speciesRestriction: [Human, Dwarf, Felinid, Oni, Arachne] # EE - Felinid, Oni, Arachne sexRestriction: [Male] # DeltaV: Splitting the scars and tattoos followSkinColor: true sprites: diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/tattoos.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/tattoos.yml index 6310f1b34f2..024bc7831aa 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/tattoos.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/tattoos.yml @@ -2,7 +2,7 @@ id: TattooHiveChest bodyPart: Chest markingCategory: Chest - speciesRestriction: [Human, Dwarf, SlimePerson, Felinid, Oni] # Delta V - SlimePerson, Felinid, Oni + speciesRestriction: [Human, Dwarf, SlimePerson, Felinid, Oni, Arachne] # Delta V - SlimePerson, Felinid, Oni # EE - Arachne sexRestriction: [Male] # DeltaV: Splitting the scars and tattoos coloring: default: @@ -17,7 +17,7 @@ id: TattooNightlingChest bodyPart: Chest markingCategory: Chest - speciesRestriction: [Human, Dwarf, SlimePerson, Felinid, Oni] # Delta V - SlimePerson, Felinid, Oni + speciesRestriction: [Human, Dwarf, SlimePerson, Felinid, Oni, Arachne] # Delta V - SlimePerson, Felinid, Oni # EE - Arachne sexRestriction: [Male] # DeltaV: Splitting the scars and tattoos coloring: default: @@ -32,7 +32,7 @@ id: TattooSilverburghLeftLeg bodyPart: LLeg markingCategory: Legs - speciesRestriction: [Human, Dwarf, Felinid, Oni] # Delta V - Felinid, Oni + speciesRestriction: [Human, Dwarf, Felinid, Oni, Arachne] # Delta V - Felinid, Oni # EE - Arachne coloring: default: type: @@ -46,7 +46,7 @@ id: TattooSilverburghRightLeg bodyPart: RLeg markingCategory: Legs - speciesRestriction: [Human, Dwarf, Felinid, Oni] # Delta V - Felinid, Oni + speciesRestriction: [Human, Dwarf, Felinid, Oni, Arachne] # Delta V - Felinid, Oni # EE - Arachne coloring: default: type: @@ -60,7 +60,7 @@ id: TattooCampbellLeftArm bodyPart: LArm markingCategory: Arms - speciesRestriction: [Human, Dwarf, Felinid, Oni] # Delta V - Felinid, Oni + speciesRestriction: [Human, Dwarf, Felinid, Oni, Arachne] # Delta V - Felinid, Oni # EE - Arachne coloring: default: type: @@ -74,7 +74,7 @@ id: TattooCampbellRightArm bodyPart: RArm markingCategory: Arms - speciesRestriction: [Human, Dwarf, Felinid, Oni] # Delta V - Felinid, Oni + speciesRestriction: [Human, Dwarf, Felinid, Oni, Arachne] # Delta V - Felinid, Oni # EE - Arachne coloring: default: type: @@ -116,7 +116,7 @@ id: TattooEyeRight bodyPart: Eyes markingCategory: Head - speciesRestriction: [Human, SlimePerson, Reptilian, Dwarf, Felinid, Vulpkanin, Oni, Harpy, Rodentia] # Delta V - Felinid, Vulpkanin, Oni, Harpy, Rodentia + speciesRestriction: [Human, SlimePerson, Reptilian, Dwarf, Felinid, Vulpkanin, Oni, Harpy, Rodentia, Arachne] # Delta V - Felinid, Vulpkanin, Oni, Harpy, Rodentia # EE - Arachne coloring: default: type: @@ -130,7 +130,7 @@ id: TattooEyeLeft bodyPart: Eyes markingCategory: Head - speciesRestriction: [Human, SlimePerson, Reptilian, Dwarf, Felinid, Vulpkanin, Oni, Harpy, Rodentia] # Delta V - Felinid, Vulpkanin, Oni, Harpy, Rodentia + speciesRestriction: [Human, SlimePerson, Reptilian, Dwarf, Felinid, Vulpkanin, Oni, Harpy, Rodentia, Arachne] # Delta V - Felinid, Vulpkanin, Oni, Harpy, Rodentia # EE - Arachne coloring: default: type: diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml b/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml index 1891cf0b065..4970f843ad2 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml @@ -37,6 +37,10 @@ state: "torso_m" - type: BodyPart #"Other" type slotId: thorax + - type: ContainerContainer + containers: + bodypart: !type:Container + ents: [ ] - type: Extractable juiceSolution: reagents: @@ -77,6 +81,6 @@ - type: BodyPart partType: Leg symmetry: Left - - type: MovementBodyPart # should actual spiders get a seperate part from arachne? + - type: MovementBodyPart #should actual spiders get a seperate part from arachne? walkSpeed : 2.7 sprintSpeed : 5 diff --git a/Resources/Prototypes/Reagents/biological.yml b/Resources/Prototypes/Reagents/biological.yml index 6490e87ffb1..4e678a29cae 100644 --- a/Resources/Prototypes/Reagents/biological.yml +++ b/Resources/Prototypes/Reagents/biological.yml @@ -23,11 +23,38 @@ - !type:OrganType type: Human shouldHave: false + - !type:SatiateHunger # begin EE + factor: 0.5 + conditions: + - !type:OrganType + type: Vampiric + - !type:AdjustReagent + conditions: + - !type:OrganType + type: Vampiric + reagent: Water + amount: 0.15 + - !type:AdjustReagent + conditions: + - !type:OrganType + type: Vampiric + reagent: Protein + amount: 0.125 + - !type:AdjustReagent + conditions: + - !type:OrganType + type: Vampiric + reagent: Omnizine + amount: 0.2 # end EE Food: effects: - !type:AdjustReagent reagent: UncookedAnimalProteins amount: 0.1 + conditions: # begin EE + - !type:OrganType + type: Vampiric + shouldHave: false # end EE Medicine: effects: - !type:HealthChange diff --git a/Resources/Prototypes/_DV/Entities/Mobs/Customization/Markings/makeup.yml b/Resources/Prototypes/_DV/Entities/Mobs/Customization/Markings/makeup.yml index f5f83ca4224..ef940ad5f69 100644 --- a/Resources/Prototypes/_DV/Entities/Mobs/Customization/Markings/makeup.yml +++ b/Resources/Prototypes/_DV/Entities/Mobs/Customization/Markings/makeup.yml @@ -2,7 +2,7 @@ id: MakeupLips bodyPart: Head markingCategory: Head - speciesRestriction: [Dwarf, Human, SlimePerson, Felinid, Oni, Harpy] # Delta V - Felinid, Oni, Harpy + speciesRestriction: [Dwarf, Human, SlimePerson, Felinid, Oni, Harpy, Arachne] # Delta V - Felinid, Oni, Harpy coloring: default: type: diff --git a/Resources/Prototypes/_EE/Chemistry/metabolizer_types.yml b/Resources/Prototypes/_EE/Chemistry/metabolizer_types.yml new file mode 100644 index 00000000000..4beba1f92f7 --- /dev/null +++ b/Resources/Prototypes/_EE/Chemistry/metabolizer_types.yml @@ -0,0 +1,3 @@ +- type: metabolizerType + id: Vampiric + name: metabolizer-type-vampiric From 916a37e5e85f186c79002e58586ae8959c547884 Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Tue, 28 Jan 2025 22:38:46 -0500 Subject: [PATCH 07/26] spider --- Content.Shared/_DV/Roles/OneirophageRole.cs | 6 + .../Locale/en-US/_DV/abilities/psionic.ftl | 1 + .../_DV/ghost/roles/ghost-role-component.ftl | 6 + .../en-US/_DV/oneirophage/oneirophage.ftl | 3 + .../en-US/_DV/prototypes/roles/antags.ftl | 3 + .../ghost/roles/ghost-role-component.ftl | 3 - .../Entities/Objects/Misc/spider_web.yml | 4 +- .../Entities/Markers/Spawners/ghost_roles.yml | 21 --- .../Entities/Mobs/NPCs/mutants.yml | 138 ------------------ .../Entities/Mobs/Species/arachne.yml | 0 .../Entities/Structures/Webbing/webs.yml | 40 ++--- .../Entities/Markers/Spawners/ghost_roles.yml | 13 ++ .../Entities/Mobs/NPCs/glimmer_creatures.yml | 120 +++++++++++++++ Resources/Prototypes/_DV/GameRules/events.yml | 23 +++ .../Prototypes/_DV/Objectives/oneirophage.yml | 33 +++++ .../_DV/Roles/Antags/oneirophage.yml | 9 ++ .../_DV/Roles/MindRoles/mind_roles.yml | 12 ++ Resources/Prototypes/_EE/GameRules/events.yml | 0 Resources/Prototypes/tags.yml | 9 ++ 19 files changed, 260 insertions(+), 184 deletions(-) create mode 100644 Content.Shared/_DV/Roles/OneirophageRole.cs create mode 100644 Resources/Locale/en-US/_DV/oneirophage/oneirophage.ftl rename Resources/Prototypes/{_EE => Nyanotrasen}/Entities/Mobs/Species/arachne.yml (100%) rename Resources/Prototypes/{_EE => Nyanotrasen}/Entities/Structures/Webbing/webs.yml (64%) create mode 100644 Resources/Prototypes/_DV/Objectives/oneirophage.yml create mode 100644 Resources/Prototypes/_DV/Roles/Antags/oneirophage.yml create mode 100644 Resources/Prototypes/_EE/GameRules/events.yml diff --git a/Content.Shared/_DV/Roles/OneirophageRole.cs b/Content.Shared/_DV/Roles/OneirophageRole.cs new file mode 100644 index 00000000000..0d8f595b321 --- /dev/null +++ b/Content.Shared/_DV/Roles/OneirophageRole.cs @@ -0,0 +1,6 @@ +using Content.Shared.Roles; + +namespace Content.Shared._DV.Roles; + +[RegisterComponent] +public sealed partial class OneirophageRoleComponent : BaseMindRoleComponent; diff --git a/Resources/Locale/en-US/_DV/abilities/psionic.ftl b/Resources/Locale/en-US/_DV/abilities/psionic.ftl index 8d6ab750383..403a7785595 100644 --- a/Resources/Locale/en-US/_DV/abilities/psionic.ftl +++ b/Resources/Locale/en-US/_DV/abilities/psionic.ftl @@ -44,3 +44,4 @@ psionic-power-precognition-random-sentience-result-message = Something bright an psionic-power-precognition-unknown-shuttle-cargo-lost-result-message = You see a vision of a simple ship of old Terra, adrift of the sea, far away from home. psionic-power-precognition-unknown-shuttle-traveling-cuisine-result-message = You see a vision of peace, a cozy meal sizzling on a warm stove. A delicious smells wafts through the air. psionic-power-precognition-unknown-shuttle-disaster-evac-pod-result-message = You see a vision of death and blood, of a destruction so complete only few survive, drifting through the coldness of space. +psionic-power-precognition-oneirophage-result-message = You see a vision of blood suspended in mid air, an invisible menace whispering dreams in your mind. diff --git a/Resources/Locale/en-US/_DV/ghost/roles/ghost-role-component.ftl b/Resources/Locale/en-US/_DV/ghost/roles/ghost-role-component.ftl index f301c7a4840..2fe9332afab 100644 --- a/Resources/Locale/en-US/_DV/ghost/roles/ghost-role-component.ftl +++ b/Resources/Locale/en-US/_DV/ghost/roles/ghost-role-component.ftl @@ -60,3 +60,9 @@ deltav-ghost-role-information-salvageantag-rules = You are a salvage mob. You are allowed to attack salvagers without provocation. DO NOT GIB THEIR CORPSES! You are allowed to attack the salvage shuttle. You are NOT allowed to go to the station. If the salvagers go to the station, you can't follow them. + +ghost-role-information-oneirophage-name = Oneirophage +ghost-role-information-oneirophage-description = Nest. Lure. Ambush. Consume. +ghost-role-information-oneirophage-rules = You are a team antagonist with all Spiders. + The crew is allowed to kill you without warning. + You are allowed to attack the crew without provocation. diff --git a/Resources/Locale/en-US/_DV/oneirophage/oneirophage.ftl b/Resources/Locale/en-US/_DV/oneirophage/oneirophage.ftl new file mode 100644 index 00000000000..7fd4d50f0f5 --- /dev/null +++ b/Resources/Locale/en-US/_DV/oneirophage/oneirophage.ftl @@ -0,0 +1,3 @@ +oneirophage-round-end-name = Oneirophage + +oneirophage-role-briefing = You are the Dream Spider, spin webs of blood and fear throughout the tunnels of this fertile ground. diff --git a/Resources/Locale/en-US/_DV/prototypes/roles/antags.ftl b/Resources/Locale/en-US/_DV/prototypes/roles/antags.ftl index dd2cef59efa..aa67ca7657c 100644 --- a/Resources/Locale/en-US/_DV/prototypes/roles/antags.ftl +++ b/Resources/Locale/en-US/_DV/prototypes/roles/antags.ftl @@ -12,3 +12,6 @@ roles-antag-syndicate-synthesis-objective = Sell your finest chemicals. roles-antag-syndicate-recruiter-name = Syndicate Recruiter roles-antag-syndicate-recruiter-objective = Find and recruit the best agents for the Syndicate. + +roles-antag-oneirophage-name = Oneirophage +roles-antag-oneirophage-objective = Survive and thrive off their blood. diff --git a/Resources/Locale/en-US/nyanotrasen/ghost/roles/ghost-role-component.ftl b/Resources/Locale/en-US/nyanotrasen/ghost/roles/ghost-role-component.ftl index b999392b58d..fe933ef2ad0 100644 --- a/Resources/Locale/en-US/nyanotrasen/ghost/roles/ghost-role-component.ftl +++ b/Resources/Locale/en-US/nyanotrasen/ghost/roles/ghost-role-component.ftl @@ -1,5 +1,2 @@ -ghost-role-information-giant-spider-vampire-name = Oneirophage -ghost-role-information-giant-spider-vampire-description = Nest. Lure. Ambush. Consume. - ghost-role-information-cancer-mouse-name = Cancer Mouse ghost-role-information-cancer-mouse-description = Make off color comments, but not so edgy that they break the rules of the server. diff --git a/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml b/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml index f473eb48580..4c315257bd2 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml @@ -76,9 +76,9 @@ ignoreWhitelist: components: - IgnoreSpiderWeb - - type: Tag # DeltaV begin port Arachne from EE + - type: Tag # DeltaV port Arachne from EE tags: - - ArachneWeb # DeltaV end port Arachne from EE + - ArachneWeb - type: entity id: SpiderWebClown diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/ghost_roles.yml b/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/ghost_roles.yml index dfc55602df3..9a7fa02be89 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/ghost_roles.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/ghost_roles.yml @@ -34,24 +34,3 @@ - state: green - state: prisoner - type: MidRoundAntagSpawnLocation - -# - type: entity -# id: SpawnPointGhostVampSpider -# name: ghost role spawn point -# suffix: Vampire spider -# parent: MarkerBase -# noSpawn: true -# components: -# - type: GhostRoleMobSpawner -# prototype: MobGiantSpiderVampireAngry -# - type: GhostRole -# makeSentient: true -# name: ghost-role-information-giant-spider-vampire-name -# description: ghost-role-information-giant-spider-vampire-description -# rules: No antagonist restrictions. Just don't talk in emote; you have telepathic chat. -# - type: Sprite -# sprite: Markers/jobs.rsi -# layers: -# - state: green -# - sprite: Mobs/Animals/bat.rsi -# state: bat diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/NPCs/mutants.yml b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/NPCs/mutants.yml index 045af4d82fc..578f40ecd22 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/NPCs/mutants.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/NPCs/mutants.yml @@ -1,141 +1,3 @@ -# - type: entity -# name: oneirophage -# parent: SimpleMobBase -# id: MobGiantSpiderVampire -# description: The 'dream-eater' spider, rumored to be one of the potential genetic sources for arachne. -# components: -# - type: Sprite -# drawdepth: Mobs -# layers: -# - map: ["enum.DamageStateVisualLayers.Base"] -# state: viper -# sprite: Mobs/Animals/spider.rsi -# - type: Physics -# - type: Fixtures -# fixtures: -# fix1: -# shape: -# !type:PhysShapeCircle -# radius: 0.35 -# density: 130 -# mask: -# - SmallMobMask -# layer: -# - SmallMobLayer -# - type: Appearance -# - type: DamageStateVisuals -# states: -# Alive: -# Base: viper -# Critical: -# Base: viper_dead -# Dead: -# Base: viper_dead -# - type: Butcherable -# spawned: -# - id: FoodMeatSpider -# amount: 2 -# - type: CombatMode -# - type: ReplacementAccent -# accent: xeno -# - type: InteractionPopup -# successChance: 0.5 -# interactSuccessString: petting-success-tarantula -# interactFailureString: petting-failure-generic -# - type: Puller -# needsHands: false -# - type: Arachne -# cocoonDelay: 8 -# - type: SolutionContainerManager -# solutions: -# melee: -# reagents: -# - ReagentId: Nocturine -# Quantity: 20 -# - type: MeleeChemicalInjector -# solution: melee -# transferAmount: 3.5 -# - type: SolutionRegeneration -# solution: melee -# generated: -# reagents: -# - ReagentId: Nocturine -# Quantity: 0.15 -# - type: BloodSucker -# unitsToSucc: 35 -# injectWhenSucc: true -# injectReagent: Cryptobiolin -# unitsToInject: 10 -# webRequired: true -# - type: Bloodstream -# bloodReagent: DemonsBlood -# - type: Body -# prototype: VampiricAnimalLarge -# - type: PotentialPsionic -# - type: Psionic -# removable: false -# - type: MetapsionicPower -# - type: MeleeWeapon -# hidden: true -# angle: 0 -# animation: WeaponArcBite -# damage: -# types: -# Piercing: 8 -# - type: AntiPsionicWeapon -# punish: false -# modifiers: -# coefficients: -# Piercing: 2.25 -# - type: Damageable -# damageContainer: HalfSpirit -# damageModifierSet: HalfSpirit -# - type: StatusEffects -# allowed: -# - Stun -# - KnockedDown -# - SlowedDown -# - Stutter -# - SeeingRainbows -# - Electrocution -# - Drunk -# - SlurredSpeech -# - PressureImmunity -# - Muted -# - ForcedSleep -# - TemporaryBlindness -# - Pacified -# - PsionicsDisabled -# - PsionicallyInsulated -# - type: Tag -# tags: -# - Oneirophage -# - type: MovementAlwaysTouching -# - type: PsionicInvisibleContacts -# whitelist: -# tags: -# - ArachneWeb - -# - type: entity -# name: oneirophage -# parent: MobGiantSpiderVampire -# id: MobGiantSpiderVampireAngry -# suffix: Angry -# components: -# - type: NpcFactionMember -# factions: -# - SimpleHostile -# - type: InputMover -# - type: MobMover -# - type: HTN -# rootTask: SimpleHostileCompound -# - type: GhostRole -# makeSentient: true -# name: ghost-role-information-giant-spider-vampire-name -# description: ghost-role-information-giant-spider-vampire-description -# rules: No antagonist restrictions. Just don't talk in emote; you have telepathic chat. -# - type: GhostTakeoverAvailable - - type: entity parent: SimpleMobBase id: MobMouseCancer diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Species/arachne.yml b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/arachne.yml similarity index 100% rename from Resources/Prototypes/_EE/Entities/Mobs/Species/arachne.yml rename to Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/arachne.yml diff --git a/Resources/Prototypes/_EE/Entities/Structures/Webbing/webs.yml b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Webbing/webs.yml similarity index 64% rename from Resources/Prototypes/_EE/Entities/Structures/Webbing/webs.yml rename to Resources/Prototypes/Nyanotrasen/Entities/Structures/Webbing/webs.yml index c3e020090fd..e4a3aee793f 100644 --- a/Resources/Prototypes/_EE/Entities/Structures/Webbing/webs.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Webbing/webs.yml @@ -5,21 +5,21 @@ placement: mode: SnapgridCenter snap: - - Wall + - Wall components: - type: Sprite layers: - - sprite: Nyanotrasen/Structures/cocoon.rsi - state: cocoon_large1 - map: [ "enum.DamageStateVisualLayers.Base" ] + - sprite: Nyanotrasen/Structures/cocoon.rsi + state: cocoon_large1 + map: [ "enum.DamageStateVisualLayers.Base" ] - type: RandomSprite available: - - enum.DamageStateVisualLayers.Base: - cocoon_large1: "" - - enum.DamageStateVisualLayers.Base: #your guess for why randomsprite requires an arbitrary layer is as good as mine friend - cocoon_large2: "" - - enum.DamageStateVisualLayers.Base: - cocoon_large3: "" + - enum.DamageStateVisualLayers.Base: + cocoon_large1: "" + - enum.DamageStateVisualLayers.Base: #your guess for why randomsprite requires an arbitrary layer is as good as mine friend + cocoon_large2: "" + - enum.DamageStateVisualLayers.Base: + cocoon_large3: "" - type: Cocoon - type: Clickable - type: InteractionOutline @@ -76,18 +76,18 @@ placement: mode: SnapgridCenter snap: - - Wall + - Wall components: - type: Sprite layers: - - sprite: Nyanotrasen/Structures/cocoon.rsi - state: cocoon1 - map: [ "enum.DamageStateVisualLayers.Base" ] + - sprite: Nyanotrasen/Structures/cocoon.rsi + state: cocoon1 + map: [ "enum.DamageStateVisualLayers.Base" ] - type: RandomSprite available: - - enum.DamageStateVisualLayers.Base: - cocoon1: "" - - enum.DamageStateVisualLayers.Base: #your guess for why randomsprite requires an arbitrary layer is as good as mine friend - cocoon2: "" - - enum.DamageStateVisualLayers.Base: - cocoon3: "" + - enum.DamageStateVisualLayers.Base: + cocoon1: "" + - enum.DamageStateVisualLayers.Base: #your guess for why randomsprite requires an arbitrary layer is as good as mine friend + cocoon2: "" + - enum.DamageStateVisualLayers.Base: + cocoon3: "" diff --git a/Resources/Prototypes/_DV/Entities/Markers/Spawners/ghost_roles.yml b/Resources/Prototypes/_DV/Entities/Markers/Spawners/ghost_roles.yml index 6bff35e65e5..41c5ce659c7 100644 --- a/Resources/Prototypes/_DV/Entities/Markers/Spawners/ghost_roles.yml +++ b/Resources/Prototypes/_DV/Entities/Markers/Spawners/ghost_roles.yml @@ -123,3 +123,16 @@ - !type:RoleTimeRequirement role: JobChemist time: 7200 # 2h chemist so you know how to make CH + +- type: entity + categories: [ HideSpawnMenu, Spawner ] + parent: BaseAntagSpawner + id: SpawnPointGhostOneirophage + components: + - type: GhostRole + name: ghost-role-information-giant-oneirophage-name + description: ghost-role-information-oneirophage-description + rules: ghost-role-information-oneirophage-rules + requirements: # keep in sync with the antag prototype + - !type:OverallPlaytimeRequirement + time: 86400 # 24h so you probably know some general lore or something diff --git a/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml b/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml index b4ed2df261b..2adafeae5f5 100644 --- a/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml +++ b/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml @@ -160,3 +160,123 @@ - GlimmerMonster - type: NPCRetaliation attackMemoryLength: 10 + +- type: entity + name: oneirophage + parent: MobGiantSpider + id: Oneirophage + description: The 'dream-eater' spider, rumored to be one of the potential genetic sources for arachne. + components: + - type: GhostRole + makeSentient: true + allowSpeech: true + allowMovement: true + name: ghost-role-information-oneirophage-name + description: ghost-role-information-oneirophage-description + - type: GhostTakeoverAvailable + - type: NpcFactionMember + factions: + - SimpleHostile + - type: Sprite + drawdepth: Mobs + layers: + - map: ["enum.DamageStateVisualLayers.Base", "movement"] + state: viper + sprite: Mobs/Animals/spider.rsi + - type: SpriteMovement + movementLayers: + movement: + state: viper-moving + noMovementLayers: + movement: + state: viper + - type: Appearance + - type: DamageStateVisuals + states: + Alive: + Base: viper + Critical: + Base: viper_dead + Dead: + Base: viper_dead + - type: ReplacementAccent + accent: xeno + - type: MobStateActions + actions: + Critical: + - ActionCritSuccumb + - ActionCritFakeDeath + - ActionCritLastWords + - type: InteractionPopup + successChance: 0.5 + interactSuccessString: petting-success-tarantula + interactFailureString: petting-failure-generic + interactSuccessSpawn: EffectHearts + interactSuccessSound: + path: /Audio/Animals/snake_hiss.ogg + - type: Puller + needsHands: false + - type: Cocooner + cocoonDelay: 8 + - type: SolutionContainerManager + solutions: + melee: + reagents: + - ReagentId: Nocturine + Quantity: 20 + - type: MeleeChemicalInjector + solution: melee + transferAmount: 3.5 + - type: SolutionRegeneration + solution: melee + generated: + reagents: + - ReagentId: Nocturine + Quantity: 0.15 + - type: BloodSucker + unitsToSucc: 35 + injectWhenSucc: true + injectReagent: Cryptobiolin + unitsToInject: 10 + webRequired: true + - type: Bloodstream + bloodReagent: DemonsBlood + - type: Body + prototype: VampiricAnimalLarge + - type: PotentialPsionic + - type: Psionic + removable: false + - type: MetapsionicPower + - type: AntiPsionicWeapon + punish: false + modifiers: + coefficients: + Piercing: 2.25 + # - type: Damageable # DeltaV no + # damageContainer: HalfSpirit + # damageModifierSet: HalfSpirit + - type: StatusEffects + allowed: + - Stun + - KnockedDown + - SlowedDown + - Stutter + - SeeingRainbows + - Electrocution + - Drunk + - SlurredSpeech + - PressureImmunity + - Muted + - ForcedSleep + - TemporaryBlindness + - Pacified + - PsionicsDisabled + - PsionicallyInsulated + - type: Tag + tags: + - Oneirophage + - type: MovementAlwaysTouching + - type: PsionicInvisibleContacts + whitelist: + tags: + - ArachneWeb diff --git a/Resources/Prototypes/_DV/GameRules/events.yml b/Resources/Prototypes/_DV/GameRules/events.yml index 3ba78e31290..18fb3c84b02 100644 --- a/Resources/Prototypes/_DV/GameRules/events.yml +++ b/Resources/Prototypes/_DV/GameRules/events.yml @@ -12,6 +12,7 @@ - id: Fugitive - id: ListeningPost - id: ParadoxAnomaly + - id: Oneirophage #- id: RatKingSpawn # Replaces upstream meteor events until they're good @@ -210,3 +211,25 @@ sound: /Audio/Effects/clang.ogg mindRoles: - MindRoleFugitive + +- type: entity + parent: BaseMidRoundAntag + id: Oneirophage + components: + - type: StationEvent + duration: null + - type: PrecognitionResult + message: psionic-power-precognition-oneirophage-result-message + - type: AntagObjectives + objectives: + - OneirophageNestObjective + - OneirophageSurviveObjective + - type: AntagSelection + agentName: oneirophage-round-end-name + definitions: + - spawnerPrototype: SpawnPointGhostVampSpider + min: 1 + max: 1 + pickPlayer: false + mindRoles: + - MindRoleOneirophage diff --git a/Resources/Prototypes/_DV/Objectives/oneirophage.yml b/Resources/Prototypes/_DV/Objectives/oneirophage.yml new file mode 100644 index 00000000000..abc21ad780b --- /dev/null +++ b/Resources/Prototypes/_DV/Objectives/oneirophage.yml @@ -0,0 +1,33 @@ +- type: entity + abstract: true + parent: BaseTraitorObjective + id: BaseOneirophageObjective + components: + - type: Objective + difficulty: 0 # difficulty is unused + - type: RoleRequirement + roles: + mindRoles: + - OneirophageRole + +- type: entity + parent: [BaseOneirophageObjective, BaseSurviveObjective] + id: OneirophageSurviveObjective + description: Survive another day, and siphon dreams forever. + name: Survive + components: + - type: Objective + icon: + sprite: Objects/Misc/spider_web_2.rsi + state: icon + +- type: entity + parent: [BaseOneirophageObjective, BaseSurviveObjective] + id: OneirophageNestObjective + description: Establish a nest, rule the dark, and bathe in their sacrifices. + name: Dream Spider + components: + - type: Objective + icon: + sprite: Objects/Misc/spiderweb.rsi + state: spider_web_1 diff --git a/Resources/Prototypes/_DV/Roles/Antags/oneirophage.yml b/Resources/Prototypes/_DV/Roles/Antags/oneirophage.yml new file mode 100644 index 00000000000..8ca3870136b --- /dev/null +++ b/Resources/Prototypes/_DV/Roles/Antags/oneirophage.yml @@ -0,0 +1,9 @@ +- type: antag + id: Oneirophage + name: roles-antag-oneirophage-name + antagonist: true + objective: roles-antag-oneirophage-objective + # keep these in sync with the spawner + requirements: + - !type:OverallPlaytimeRequirement + time: 86400 # 24h so you probably know some general lore or something diff --git a/Resources/Prototypes/_DV/Roles/MindRoles/mind_roles.yml b/Resources/Prototypes/_DV/Roles/MindRoles/mind_roles.yml index 78a30855d08..20fc98f6ed4 100644 --- a/Resources/Prototypes/_DV/Roles/MindRoles/mind_roles.yml +++ b/Resources/Prototypes/_DV/Roles/MindRoles/mind_roles.yml @@ -53,3 +53,15 @@ - type: SynthesisRole - type: RoleBriefing briefing: synthesis-role-briefing + +- type: entity + parent: BaseMindRoleAntag + id: MindRoleOneirophage + name: Oneirophage Role + components: + - type: MindRole + antagPrototype: Oneirophage + exclusiveAntag: true + - type: OneirophageRole + - type: RoleBriefing + briefing: oneirophage-role-briefing diff --git a/Resources/Prototypes/_EE/GameRules/events.yml b/Resources/Prototypes/_EE/GameRules/events.yml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index 396b6251e16..080d87dfe9c 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -21,6 +21,9 @@ - type: Tag id: AppraisalTool +- type: Tag # EE + id: ArachneWeb + - type: Tag id: Arrow @@ -572,6 +575,9 @@ - type: Tag id: Fruit +- type: Tag # EE + id: FullBodyOuter + - type: Tag id: Galaxythistle @@ -921,6 +927,9 @@ - type: Tag id: Ointment +- type: Tag # EE + id: Oneirophage + - type: Tag id: Ore From e2af2b4fa86e814c3c9236ec39724053f2c72019 Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:35:39 -0500 Subject: [PATCH 08/26] take 10 --- .../Prototypes/_DV/Entities/Markers/Spawners/ghost_roles.yml | 4 +++- .../Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml | 3 ++- Resources/Prototypes/_DV/GameRules/events.yml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Resources/Prototypes/_DV/Entities/Markers/Spawners/ghost_roles.yml b/Resources/Prototypes/_DV/Entities/Markers/Spawners/ghost_roles.yml index 41c5ce659c7..41ca81f3997 100644 --- a/Resources/Prototypes/_DV/Entities/Markers/Spawners/ghost_roles.yml +++ b/Resources/Prototypes/_DV/Entities/Markers/Spawners/ghost_roles.yml @@ -130,9 +130,11 @@ id: SpawnPointGhostOneirophage components: - type: GhostRole - name: ghost-role-information-giant-oneirophage-name + name: ghost-role-information-oneirophage-name description: ghost-role-information-oneirophage-description rules: ghost-role-information-oneirophage-rules requirements: # keep in sync with the antag prototype - !type:OverallPlaytimeRequirement time: 86400 # 24h so you probably know some general lore or something + - type: GhostRoleMobSpawner + prototype: MobOneirophage diff --git a/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml b/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml index 2adafeae5f5..3d25972b1eb 100644 --- a/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml +++ b/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml @@ -164,7 +164,7 @@ - type: entity name: oneirophage parent: MobGiantSpider - id: Oneirophage + id: MobOneirophage description: The 'dream-eater' spider, rumored to be one of the potential genetic sources for arachne. components: - type: GhostRole @@ -246,6 +246,7 @@ - type: PotentialPsionic - type: Psionic removable: false + - type: GlimmerSource - type: MetapsionicPower - type: AntiPsionicWeapon punish: false diff --git a/Resources/Prototypes/_DV/GameRules/events.yml b/Resources/Prototypes/_DV/GameRules/events.yml index 18fb3c84b02..71a70db426d 100644 --- a/Resources/Prototypes/_DV/GameRules/events.yml +++ b/Resources/Prototypes/_DV/GameRules/events.yml @@ -227,7 +227,7 @@ - type: AntagSelection agentName: oneirophage-round-end-name definitions: - - spawnerPrototype: SpawnPointGhostVampSpider + - spawnerPrototype: SpawnPointGhostOneirophage min: 1 max: 1 pickPlayer: false From e140b5b074c4c5f23a50f0d1c4365e5668bf4d20 Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Wed, 29 Jan 2025 00:59:33 -0500 Subject: [PATCH 09/26] aaaa --- .../Entities/Markers/Spawners/ghost_roles.yml | 2 ++ .../Entities/Mobs/NPCs/glimmer_creatures.yml | 1 + Resources/Prototypes/_DV/GameRules/events.yml | 4 --- .../Prototypes/_DV/Objectives/oneirophage.yml | 33 ------------------- 4 files changed, 3 insertions(+), 37 deletions(-) delete mode 100644 Resources/Prototypes/_DV/Objectives/oneirophage.yml diff --git a/Resources/Prototypes/_DV/Entities/Markers/Spawners/ghost_roles.yml b/Resources/Prototypes/_DV/Entities/Markers/Spawners/ghost_roles.yml index 41ca81f3997..c949a4e3883 100644 --- a/Resources/Prototypes/_DV/Entities/Markers/Spawners/ghost_roles.yml +++ b/Resources/Prototypes/_DV/Entities/Markers/Spawners/ghost_roles.yml @@ -133,6 +133,8 @@ name: ghost-role-information-oneirophage-name description: ghost-role-information-oneirophage-description rules: ghost-role-information-oneirophage-rules + mindRoles: + - MindRoleOneirophage requirements: # keep in sync with the antag prototype - !type:OverallPlaytimeRequirement time: 86400 # 24h so you probably know some general lore or something diff --git a/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml b/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml index 3d25972b1eb..c2e2613ccf6 100644 --- a/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml +++ b/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml @@ -173,6 +173,7 @@ allowMovement: true name: ghost-role-information-oneirophage-name description: ghost-role-information-oneirophage-description + rules: ghost-role-information-oneirophage-rules - type: GhostTakeoverAvailable - type: NpcFactionMember factions: diff --git a/Resources/Prototypes/_DV/GameRules/events.yml b/Resources/Prototypes/_DV/GameRules/events.yml index 71a70db426d..18700406564 100644 --- a/Resources/Prototypes/_DV/GameRules/events.yml +++ b/Resources/Prototypes/_DV/GameRules/events.yml @@ -220,10 +220,6 @@ duration: null - type: PrecognitionResult message: psionic-power-precognition-oneirophage-result-message - - type: AntagObjectives - objectives: - - OneirophageNestObjective - - OneirophageSurviveObjective - type: AntagSelection agentName: oneirophage-round-end-name definitions: diff --git a/Resources/Prototypes/_DV/Objectives/oneirophage.yml b/Resources/Prototypes/_DV/Objectives/oneirophage.yml deleted file mode 100644 index abc21ad780b..00000000000 --- a/Resources/Prototypes/_DV/Objectives/oneirophage.yml +++ /dev/null @@ -1,33 +0,0 @@ -- type: entity - abstract: true - parent: BaseTraitorObjective - id: BaseOneirophageObjective - components: - - type: Objective - difficulty: 0 # difficulty is unused - - type: RoleRequirement - roles: - mindRoles: - - OneirophageRole - -- type: entity - parent: [BaseOneirophageObjective, BaseSurviveObjective] - id: OneirophageSurviveObjective - description: Survive another day, and siphon dreams forever. - name: Survive - components: - - type: Objective - icon: - sprite: Objects/Misc/spider_web_2.rsi - state: icon - -- type: entity - parent: [BaseOneirophageObjective, BaseSurviveObjective] - id: OneirophageNestObjective - description: Establish a nest, rule the dark, and bathe in their sacrifices. - name: Dream Spider - components: - - type: Objective - icon: - sprite: Objects/Misc/spiderweb.rsi - state: spider_web_1 From e9e070ed5b15a109cfd4302f8581f54dec0e6f65 Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:43:51 -0500 Subject: [PATCH 10/26] succ to suck, not funny --- .../_EE/Vampire/BloodSuckerComponent.cs | 10 +++++----- .../_EE/Vampire/BloodSuckerSystem.cs | 18 +++++++++--------- .../Injector/BloodSuckerGlandInjectorSystem.cs | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Content.Server/_EE/Vampire/BloodSuckerComponent.cs b/Content.Server/_EE/Vampire/BloodSuckerComponent.cs index 65c0f33cce4..e7bd70f91c5 100644 --- a/Content.Server/_EE/Vampire/BloodSuckerComponent.cs +++ b/Content.Server/_EE/Vampire/BloodSuckerComponent.cs @@ -6,8 +6,8 @@ public sealed partial class BloodSuckerComponent : Component /// /// How much to suck each time we suck. /// - [DataField("unitsToSucc")] - public float UnitsToSucc = 20f; + [DataField("unitsToSuck")] + public float UnitsToSuck = 20f; /// /// The time (in seconds) that it takes to suck an entity. @@ -15,13 +15,13 @@ public sealed partial class BloodSuckerComponent : Component [DataField, ViewVariables(VVAccess.ReadWrite)] public TimeSpan Delay = TimeSpan.FromSeconds(4); - // ***INJECT WHEN SUCC*** + // ***INJECT WHEN SUCK*** /// /// Whether to inject chems into a chemstream when we suck something. /// - [DataField("injectWhenSucc")] - public bool InjectWhenSucc = false; + [DataField("injectWhenSuck")] + public bool InjectWhenSuck = false; /// /// How many units of our injected chem to inject. diff --git a/Content.Server/_EE/Vampire/BloodSuckerSystem.cs b/Content.Server/_EE/Vampire/BloodSuckerSystem.cs index e3b18204351..e68d1efb9a6 100644 --- a/Content.Server/_EE/Vampire/BloodSuckerSystem.cs +++ b/Content.Server/_EE/Vampire/BloodSuckerSystem.cs @@ -39,13 +39,13 @@ public sealed class BloodSuckerSystem : EntitySystem public override void Initialize() { base.Initialize(); - SubscribeLocalEvent>(AddSuccVerb); + SubscribeLocalEvent>(AddSuckVerb); SubscribeLocalEvent(OnHealthExamined); SubscribeLocalEvent(OnDamageChanged); SubscribeLocalEvent(OnDoAfter); } - private void AddSuccVerb(EntityUid uid, BloodSuckerComponent component, GetVerbsEvent args) + private void AddSuckVerb(EntityUid uid, BloodSuckerComponent component, GetVerbsEvent args) { var victim = args.Target; @@ -65,7 +65,7 @@ private void AddSuccVerb(EntityUid uid, BloodSuckerComponent component, GetVerbs { Act = () => { - StartSuccDoAfter(uid, victim, component, bloodstream, !ignoreClothes); // start doafter + StartSuckDoAfter(uid, victim, component, bloodstream, !ignoreClothes); // start doafter }, Text = Loc.GetString("action-name-suck-blood"), Icon = new SpriteSpecifier.Texture(new("/Textures/Nyanotrasen/Icons/verbiconfangs.png")), @@ -96,10 +96,10 @@ private void OnDoAfter(EntityUid uid, BloodSuckerComponent component, BloodSuckD if (args.Cancelled || args.Handled || args.Args.Target == null) return; - args.Handled = TrySucc(uid, args.Args.Target.Value); + args.Handled = TrySuck(uid, args.Args.Target.Value); } - public void StartSuccDoAfter(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodSuckerComponent = null, BloodstreamComponent? stream = null, bool doChecks = true) + public void StartSuckDoAfter(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodSuckerComponent = null, BloodstreamComponent? stream = null, bool doChecks = true) { if (!Resolve(bloodsucker, ref bloodSuckerComponent) || !Resolve(victim, ref stream)) return; @@ -143,7 +143,7 @@ public void StartSuccDoAfter(EntityUid bloodsucker, EntityUid victim, BloodSucke _doAfter.TryStartDoAfter(args); } - public bool TrySucc(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodsuckerComp = null) + public bool TrySuck(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodsuckerComp = null) { // Is bloodsucker a bloodsucker? if (!Resolve(bloodsucker, ref bloodsuckerComp)) @@ -177,7 +177,7 @@ public bool TrySucc(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponen _adminLogger.Add(Shared.Database.LogType.MeleeHit, Shared.Database.LogImpact.Medium, $"{ToPrettyString(bloodsucker):player} sucked blood from {ToPrettyString(victim):target}"); - // All good, succ time. + // All good, bloodsucking time. _audio.PlayPvs("/Audio/Items/drink.ogg", bloodsucker); _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked", ("target", victim)), bloodsucker, bloodsucker, Shared.Popups.PopupType.Medium); @@ -187,7 +187,7 @@ public bool TrySucc(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponen if (bloodstream.BloodSolution == null) return false; - var temp = _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSucc); + var temp = _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSuck); _stomachSystem.TryTransferSolution(bloodsucker, temp, stomach); // DeltaV // Add a little pierce @@ -197,7 +197,7 @@ public bool TrySucc(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponen _damageableSystem.TryChangeDamage(victim, damage, true, true); //I'm not porting the nocturine gland, this code is deprecated, and will be reworked at a later date. - //if (bloodsuckerComp.InjectWhenSucc && _solutionSystem.TryGetInjectableSolution(victim, out var injectable)) + //if (bloodsuckerComp.InjectWhenSuck && _solutionSystem.TryGetInjectableSolution(victim, out var injectable)) //{ // _solutionSystem.TryAddReagent(victim, injectable, bloodsuckerComp.InjectReagent, bloodsuckerComp.UnitsToInject, out var acceptedQuantity); //} diff --git a/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs b/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs index 3c24acbded2..d1aa72ff125 100644 --- a/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs +++ b/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs @@ -25,7 +25,7 @@ private void OnAfterInteract(EntityUid uid, BloodSuckerGlandInjectorComponent co return; // They already have one. - if (bloodSuckerComponent.InjectWhenSucc) + if (bloodSuckerComponent.InjectWhenSuck) return; bloodSuckerComponent.InjectWhenSucc = true; From dc448112f42808cdbfb3f1b9f867d54aec47948f Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:56:03 -0500 Subject: [PATCH 11/26] removesucc 2 --- .../_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs | 2 +- .../Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs b/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs index d1aa72ff125..480c60218a8 100644 --- a/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs +++ b/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs @@ -28,7 +28,7 @@ private void OnAfterInteract(EntityUid uid, BloodSuckerGlandInjectorComponent co if (bloodSuckerComponent.InjectWhenSuck) return; - bloodSuckerComponent.InjectWhenSucc = true; + bloodSuckerComponent.InjectWhenSuck = true; bloodSuckerComponent.InjectReagent = component.InjectReagent; bloodSuckerComponent.UnitsToInject = component.UnitsToInject; component.Used = true; diff --git a/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml b/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml index c2e2613ccf6..c3f7223a1b3 100644 --- a/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml +++ b/Resources/Prototypes/_DV/Entities/Mobs/NPCs/glimmer_creatures.yml @@ -235,8 +235,8 @@ - ReagentId: Nocturine Quantity: 0.15 - type: BloodSucker - unitsToSucc: 35 - injectWhenSucc: true + unitsToSuck: 35 + injectWhenSuck: true injectReagent: Cryptobiolin unitsToInject: 10 webRequired: true From 72603553f2682fc2efe3270fb96a9783200e13dc Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Wed, 29 Jan 2025 16:38:14 -0500 Subject: [PATCH 12/26] refactor gaming --- .../_EE/Vampire/BloodSuckerSystem.cs | 99 +++++++++---------- 1 file changed, 48 insertions(+), 51 deletions(-) diff --git a/Content.Server/_EE/Vampire/BloodSuckerSystem.cs b/Content.Server/_EE/Vampire/BloodSuckerSystem.cs index e68d1efb9a6..182a29f74ca 100644 --- a/Content.Server/_EE/Vampire/BloodSuckerSystem.cs +++ b/Content.Server/_EE/Vampire/BloodSuckerSystem.cs @@ -143,65 +143,62 @@ public void StartSuckDoAfter(EntityUid bloodsucker, EntityUid victim, BloodSucke _doAfter.TryStartDoAfter(args); } - public bool TrySuck(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodsuckerComp = null) - { - // Is bloodsucker a bloodsucker? - if (!Resolve(bloodsucker, ref bloodsuckerComp)) - return false; - - // Does victim have a bloodstream? - if (!TryComp(victim, out var bloodstream)) - return false; - - // No blood left, yikes. - if (_bloodstreamSystem.GetBloodLevelPercentage(victim, bloodstream) == 0.0f) - return false; - - // Does bloodsucker have a stomach? - var stomachList = _bodySystem.GetBodyOrganEntityComps(bloodsucker); - if (stomachList.Count == 0) - return false; - - var stomach = stomachList.FirstOrDefault(); // DeltaV + public bool TrySuck(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodsuckerComp = null) // begin DetlaV +{ + if (!Resolve(bloodsucker, ref bloodsuckerComp)) return false; + if (!TryValidateVictim(victim)) return false; - if (!_solutionSystem.TryGetSolution(bloodsucker, StomachSystem.DefaultSolutionName, out var stomachSolution)) - return false; + if (!TryGetBloodsuckerStomach(bloodsucker, out var stomach)) return false; + if (!TryValidateSolution(bloodsucker)) return false; - // Are we too full? + PlayBloodSuckEffects(bloodsucker, victim); + return CompleteBloodSuck(bloodsucker, victim, stomach, bloodsuckerComp); +} - if (_solutionSystem.PercentFull(bloodsucker) >= 1) - { - _popups.PopupEntity(Loc.GetString("drink-component-try-use-drink-had-enough"), bloodsucker, bloodsucker, Shared.Popups.PopupType.MediumCaution); - return false; - } +private bool TryValidateVictim(EntityUid victim) +{ + if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) return false; + if (_bloodstreamSystem.GetBloodLevelPercentage(victim, bloodstream) == 0.0f) return false; + return true; +} - _adminLogger.Add(Shared.Database.LogType.MeleeHit, Shared.Database.LogImpact.Medium, $"{ToPrettyString(bloodsucker):player} sucked blood from {ToPrettyString(victim):target}"); +private bool TryGetBloodsuckerStomach(EntityUid bloodsucker, out StomachComponent stomach) +{ + stomach = _bodySystem.GetBodyOrganEntityComps(bloodsucker).FirstOrDefault(); + return stomach != null; +} - // All good, bloodsucking time. - _audio.PlayPvs("/Audio/Items/drink.ogg", bloodsucker); - _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); - _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked", ("target", victim)), bloodsucker, bloodsucker, Shared.Popups.PopupType.Medium); - EnsureComp(victim); +private bool TryValidateSolution(EntityUid bloodsucker) +{ + if (_solutionSystem.PercentFull(bloodsucker) >= 1) + { + _popups.PopupEntity(Loc.GetString("drink-component-try-use-drink-had-enough"), bloodsucker, bloodsucker, Shared.Popups.PopupType.MediumCaution); + return false; + } + return true; +} - // Make everything actually ingest. - if (bloodstream.BloodSolution == null) - return false; +private void PlayBloodSuckEffects(EntityUid bloodsucker, EntityUid victim) +{ + _adminLogger.Add(Shared.Database.LogType.MeleeHit, Shared.Database.LogImpact.Medium, $"{ToPrettyString(bloodsucker):player} sucked blood from {ToPrettyString(victim):target}"); + _audio.PlayPvs("/Audio/Items/drink.ogg", bloodsucker); + _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); + _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked", ("target", victim)), bloodsucker, bloodsucker, Shared.Popups.PopupType.Medium); + EnsureComp(victim); +} - var temp = _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSuck); - _stomachSystem.TryTransferSolution(bloodsucker, temp, stomach); // DeltaV +private bool CompleteBloodSuck(EntityUid bloodsucker, EntityUid victim, StomachComponent stomach, BloodSuckerComponent bloodsuckerComp) +{ + if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) return false; - // Add a little pierce - DamageSpecifier damage = new(); - damage.DamageDict.Add("Piercing", 1); // Slowly accumulate enough to gib after like half an hour + var extractedBlood = _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSuck); + _stomachSystem.TryTransferSolution(bloodsucker, extractedBlood, stomach); - _damageableSystem.TryChangeDamage(victim, damage, true, true); + DamageSpecifier damage = new(); + damage.DamageDict.Add("Piercing", 1); + _damageableSystem.TryChangeDamage(victim, damage, true, true); - //I'm not porting the nocturine gland, this code is deprecated, and will be reworked at a later date. - //if (bloodsuckerComp.InjectWhenSuck && _solutionSystem.TryGetInjectableSolution(victim, out var injectable)) - //{ - // _solutionSystem.TryAddReagent(victim, injectable, bloodsuckerComp.InjectReagent, bloodsuckerComp.UnitsToInject, out var acceptedQuantity); - //} - return true; - } - } + return true; } + } +} // End DeltaV From b15e4a65414951cfac9bdce76bd3ea63503bc98d Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Wed, 29 Jan 2025 18:34:55 -0500 Subject: [PATCH 13/26] spider real --- .../OuterClothing/base_clothingouter.yml | 1 + .../Prototypes/Entities/Mobs/NPCs/animals.yml | 3 + .../Entities/Clothing/OuterClothing/armor.yml | 1 + .../Entities/Mobs/Species/arachne.yml | 19 ++- .../arachne_inventory_template.yml | 121 ++++++++++++++++++ Resources/Prototypes/_EE/tag.yml | 5 + Resources/Prototypes/tags.yml | 9 -- .../Arachne/displacement.rsi/jumpsuit.png | Bin 0 -> 266 bytes .../Arachne/displacement.rsi/meta.json | 18 +++ 9 files changed, 165 insertions(+), 12 deletions(-) rename Resources/Prototypes/{Nyanotrasen => _DV}/Entities/Mobs/Species/arachne.yml (94%) create mode 100644 Resources/Prototypes/_DV/InventoryTemplates/arachne_inventory_template.yml create mode 100644 Resources/Prototypes/_EE/tag.yml create mode 100644 Resources/Textures/_DV/Mobs/Species/Arachne/displacement.rsi/jumpsuit.png create mode 100644 Resources/Textures/_DV/Mobs/Species/Arachne/displacement.rsi/meta.json diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml index af7c0d07f8b..7b28a8daa03 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml @@ -168,6 +168,7 @@ - type: Tag tags: - HidesHarpyWings # DeltaV: Used by harpies to help render their hardsuit sprites + - SuitEVA # DeltaV used to prevent arachne - type: ProtectedFromStepTriggers slots: WITHOUT_POCKET - type: DamageOnInteractProtection diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 7acdeb6786e..4548b9a4494 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -2424,6 +2424,9 @@ groups: Brute: -0.07 Burn: -0.07 + - type: BloodSucker # begin EE + webRequired: true + - type: Cocooner # end EE - type: entity parent: MobSpiderBase diff --git a/Resources/Prototypes/_DV/Entities/Clothing/OuterClothing/armor.yml b/Resources/Prototypes/_DV/Entities/Clothing/OuterClothing/armor.yml index b75dd976ea9..fe1ef1dd4a0 100644 --- a/Resources/Prototypes/_DV/Entities/Clothing/OuterClothing/armor.yml +++ b/Resources/Prototypes/_DV/Entities/Clothing/OuterClothing/armor.yml @@ -82,3 +82,4 @@ tags: - BorgSecurityArmour - WhitelistChameleon # Inherited from Parent + - Hardsuit # this is not a hardsuit but we dont want arachne using it diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/arachne.yml b/Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml similarity index 94% rename from Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/arachne.yml rename to Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml index 8dd6e62f1bc..2f61a06c4ab 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/arachne.yml +++ b/Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml @@ -101,7 +101,13 @@ - type: Speech speechSounds: Alto - type: Inventory - templateId: anytaur + templateId: arachne + displacements: + jumpsuit: + sizeMaps: + 32: + sprite: _DV/Mobs/Species/Arachne/displacement.rsi + state: jumpsuit - type: Tag tags: - CanPilot @@ -142,9 +148,10 @@ - type: entity save: false - name: Urist McHands + name: Urist McArachne parent: MobHumanDummy id: MobArachneDummy + categories: [ HideSpawnMenu ] noSpawn: true description: A dummy arachne meant to be used in character setup. components: @@ -220,6 +227,12 @@ state: none visible: false - type: Inventory - templateId: anytaur + templateId: arachne + displacements: + jumpsuit: + sizeMaps: + 32: + sprite: _DV/Mobs/Species/Arachne/displacement.rsi + state: jumpsuit - type: HumanoidAppearance species: Arachne diff --git a/Resources/Prototypes/_DV/InventoryTemplates/arachne_inventory_template.yml b/Resources/Prototypes/_DV/InventoryTemplates/arachne_inventory_template.yml new file mode 100644 index 00000000000..941a9d61309 --- /dev/null +++ b/Resources/Prototypes/_DV/InventoryTemplates/arachne_inventory_template.yml @@ -0,0 +1,121 @@ +#human but no shoes or full body +- type: inventoryTemplate + id: arachne + slots: + - name: jumpsuit + slotTexture: uniform + slotFlags: INNERCLOTHING + stripTime: 6 + uiWindowPos: 0,1 + strippingWindowPos: 0,2 + displayName: Jumpsuit + - name: outerClothing + slotTexture: suit + slotFlags: OUTERCLOTHING + stripTime: 6 + uiWindowPos: 1,1 + strippingWindowPos: 1,2 + displayName: Suit + blacklist: + tags: + - Hardsuit + - SuitEVA + - name: gloves + slotTexture: gloves + slotFlags: GLOVES + uiWindowPos: 2,1 + strippingWindowPos: 2,2 + displayName: Gloves + - name: neck + slotTexture: neck + slotFlags: NECK + uiWindowPos: 0,2 + strippingWindowPos: 0,1 + displayName: Neck + - name: mask + slotTexture: mask + slotFlags: MASK + uiWindowPos: 1,2 + strippingWindowPos: 1,1 + displayName: Mask + - name: eyes + slotTexture: glasses + slotFlags: EYES + stripTime: 3 + uiWindowPos: 0,3 + strippingWindowPos: 0,0 + displayName: Eyes + - name: ears + slotTexture: ears + slotFlags: EARS + stripTime: 3 + uiWindowPos: 2,2 + strippingWindowPos: 2,0 + displayName: Ears + - name: head + slotTexture: head + slotFlags: HEAD + uiWindowPos: 1,3 + strippingWindowPos: 1,0 + displayName: Head + - name: pocket1 + slotTexture: pocket + fullTextureName: template_small + slotFlags: POCKET + slotGroup: MainHotbar + stripTime: 3 + uiWindowPos: 0,3 + strippingWindowPos: 0,4 + dependsOn: jumpsuit + displayName: Pocket 1 + stripHidden: true + - name: pocket2 + slotTexture: pocket + fullTextureName: template_small + slotFlags: POCKET + slotGroup: MainHotbar + stripTime: 3 + uiWindowPos: 2,3 + strippingWindowPos: 1,4 + dependsOn: jumpsuit + displayName: Pocket 2 + stripHidden: true + - name: suitstorage + slotTexture: suit_storage + slotFlags: SUITSTORAGE + slotGroup: MainHotbar + stripTime: 3 + uiWindowPos: 2,0 + strippingWindowPos: 2,5 + dependsOn: outerClothing + dependsOnComponents: + - type: AllowSuitStorage + displayName: Suit Storage + - name: id + slotTexture: id + fullTextureName: template_small + slotFlags: IDCARD + slotGroup: SecondHotbar + stripTime: 6 + uiWindowPos: 2,1 + strippingWindowPos: 2,4 + dependsOn: jumpsuit + displayName: ID + - name: belt + slotTexture: belt + fullTextureName: template_small + slotFlags: BELT + slotGroup: SecondHotbar + stripTime: 6 + uiWindowPos: 3,1 + strippingWindowPos: 1,5 + displayName: Belt + - name: back + slotTexture: back + fullTextureName: template_small + slotFlags: BACK + slotGroup: SecondHotbar + stripTime: 6 + uiWindowPos: 3,0 + strippingWindowPos: 0,5 + displayName: Back diff --git a/Resources/Prototypes/_EE/tag.yml b/Resources/Prototypes/_EE/tag.yml new file mode 100644 index 00000000000..1a468429c1b --- /dev/null +++ b/Resources/Prototypes/_EE/tag.yml @@ -0,0 +1,5 @@ +- type: Tag # EE + id: ArachneWeb + +- type: Tag # EE + id: Oneirophage diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index 080d87dfe9c..396b6251e16 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -21,9 +21,6 @@ - type: Tag id: AppraisalTool -- type: Tag # EE - id: ArachneWeb - - type: Tag id: Arrow @@ -575,9 +572,6 @@ - type: Tag id: Fruit -- type: Tag # EE - id: FullBodyOuter - - type: Tag id: Galaxythistle @@ -927,9 +921,6 @@ - type: Tag id: Ointment -- type: Tag # EE - id: Oneirophage - - type: Tag id: Ore diff --git a/Resources/Textures/_DV/Mobs/Species/Arachne/displacement.rsi/jumpsuit.png b/Resources/Textures/_DV/Mobs/Species/Arachne/displacement.rsi/jumpsuit.png new file mode 100644 index 0000000000000000000000000000000000000000..ebf250c5b82b67c8c42ef2f30efa799e0f0bec97 GIT binary patch literal 266 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|j(EB_hE&XX zd&`io*+Aq#K+x9*J1eW1*jyg)ZoJNOf1}d0^D{pGkd^*?k!coF2BR Date: Wed, 29 Jan 2025 21:22:15 -0500 Subject: [PATCH 14/26] yaml --- .../Prototypes/{_EE => _DV}/Entities/Mobs/Player/arachne.yml | 0 Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml | 2 -- 2 files changed, 2 deletions(-) rename Resources/Prototypes/{_EE => _DV}/Entities/Mobs/Player/arachne.yml (100%) diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Player/arachne.yml b/Resources/Prototypes/_DV/Entities/Mobs/Player/arachne.yml similarity index 100% rename from Resources/Prototypes/_EE/Entities/Mobs/Player/arachne.yml rename to Resources/Prototypes/_DV/Entities/Mobs/Player/arachne.yml diff --git a/Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml b/Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml index 2f61a06c4ab..a8a7dc57a79 100644 --- a/Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml +++ b/Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml @@ -115,7 +115,6 @@ - DoorBumpOpener - type: Bloodstream bloodReagent: DemonsBlood - bloodRegenerationThirst: 4 # 1 unit of demon's blood satiates 4 thirst - type: BloodSucker webRequired: true - type: Cocooner @@ -152,7 +151,6 @@ parent: MobHumanDummy id: MobArachneDummy categories: [ HideSpawnMenu ] - noSpawn: true description: A dummy arachne meant to be used in character setup. components: - type: Sprite From f0fe39f14d8c78482e754370d62b7e4b6ae87391 Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Wed, 29 Jan 2025 22:32:22 -0500 Subject: [PATCH 15/26] arachne damage mods --- Resources/Prototypes/_DV/Damage/modifier_sets.yml | 12 ++++++++++++ .../_DV/Entities/Mobs/Species/arachne.yml | 13 ++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Resources/Prototypes/_DV/Damage/modifier_sets.yml b/Resources/Prototypes/_DV/Damage/modifier_sets.yml index a9a5eff4900..32d5e55208f 100644 --- a/Resources/Prototypes/_DV/Damage/modifier_sets.yml +++ b/Resources/Prototypes/_DV/Damage/modifier_sets.yml @@ -39,3 +39,15 @@ Cold: 1.1 Shock: 1.15 Radiation: 0.2 + +- type: damageModifierSet + id: Arachne + coefficients: + Cold: 0.5 + Blunt: 0.9 + Slash: 0.8 + Piercing: 0.8 + Heat: 1.25 + Radiation: 1.25 + flatReductions: + Cold: 3 diff --git a/Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml b/Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml index a8a7dc57a79..018c61c1824 100644 --- a/Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml +++ b/Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml @@ -100,6 +100,16 @@ requiredLegs: 8 - type: Speech speechSounds: Alto + - type: Damageable + damageContainer: Biological + damageModifierSet: Arachne + - type: MeleeWeapon + animation: WeaponArcBite + soundHit: + path: /Audio/Effects/bite.ogg + damage: + types: + Piercing: 5 - type: Inventory templateId: arachne displacements: @@ -131,9 +141,6 @@ types: Blunt: 0.05 #per second, scales with pressure and other constants. Reduced Damage. This allows medicine to heal faster than damage. - type: MovementAlwaysTouching - - type: MovementSpeedModifier - baseWalkSpeed : 3.0 - baseSprintSpeed : 5.0 - type: FireVisuals sprite: Mobs/Effects/onfire.rsi normalState: Generic_mob_burning From 5163f7236721aafac90b788392377582e3fd01b5 Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Thu, 30 Jan 2025 14:21:31 -0500 Subject: [PATCH 16/26] namespace --- .../{_EE => _DV}/Cocoon/CocoonSystem.cs | 6 ++-- .../{_EE => _DV}/Cocoon/CocoonerSystem.cs | 28 +++++++++--------- .../Vampire/BloodSuckedComponent.cs | 2 +- .../Vampire/BloodSuckerComponent.cs | 2 +- .../{_EE => _DV}/Vampire/BloodSuckerSystem.cs | 26 ++++++++-------- .../BloodSuckerGlandInjectorComponent.cs | 2 +- .../BloodSuckerGlandInjectorSystem.cs | 3 +- .../{_EE => _DV}/Cocoon/CocoonComponent.cs | 2 +- .../{_EE => _DV}/Cocoon/CocoonDoAfterEvent.cs | 4 +-- .../{_EE => _DV}/Cocoon/CocoonerComponent.cs | 2 +- .../Vampiric/BloodSuckDoAfterEvent.cs | 4 +-- .../Entities/Body/Mechanisms/vampiric.yml | 0 .../Entities/Body/Parts/spider.yml | 0 .../Entities/Body/Prototypes/arachne.yml | 0 .../Body/Prototypes/vampiricanimal.yml | 0 .../Entities/Structures/Webbing/webs.yml | 0 .../Mobs/Species/arachne.rsi/meta.json | 0 .../Mobs/Species/arachne.rsi/spider_body.png | Bin .../Species/arachne.rsi/spider_body_front.png | Bin .../Mobs/Species/eyes.rsi/eyes.png | Bin .../Mobs/Species/eyes.rsi/meta.json | 0 .../Structures/cocoon.rsi/cocoon1.png | Bin .../Structures/cocoon.rsi/cocoon2.png | Bin .../Structures/cocoon.rsi/cocoon3.png | Bin .../Structures/cocoon.rsi/cocoon_large1.png | Bin .../Structures/cocoon.rsi/cocoon_large2.png | Bin .../Structures/cocoon.rsi/cocoon_large3.png | Bin .../Structures/cocoon.rsi/meta.json | 0 28 files changed, 40 insertions(+), 41 deletions(-) rename Content.Client/{_EE => _DV}/Cocoon/CocoonSystem.cs (95%) rename Content.Server/{_EE => _DV}/Cocoon/CocoonerSystem.cs (98%) rename Content.Server/{_EE => _DV}/Vampire/BloodSuckedComponent.cs (82%) rename Content.Server/{_EE => _DV}/Vampire/BloodSuckerComponent.cs (97%) rename Content.Server/{_EE => _DV}/Vampire/BloodSuckerSystem.cs (98%) rename Content.Server/{_EE => _DV}/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs (92%) rename Content.Server/{_EE => _DV}/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs (95%) rename Content.Shared/{_EE => _DV}/Cocoon/CocoonComponent.cs (87%) rename Content.Shared/{_EE => _DV}/Cocoon/CocoonDoAfterEvent.cs (89%) rename Content.Shared/{_EE => _DV}/Cocoon/CocoonerComponent.cs (90%) rename Content.Shared/{_EE => _DV}/Vampiric/BloodSuckDoAfterEvent.cs (83%) rename Resources/Prototypes/{Nyanotrasen => _DV}/Entities/Body/Mechanisms/vampiric.yml (100%) rename Resources/Prototypes/{Nyanotrasen => _DV}/Entities/Body/Parts/spider.yml (100%) rename Resources/Prototypes/{Nyanotrasen => _DV}/Entities/Body/Prototypes/arachne.yml (100%) rename Resources/Prototypes/{Nyanotrasen => _DV}/Entities/Body/Prototypes/vampiricanimal.yml (100%) rename Resources/Prototypes/{Nyanotrasen => _DV}/Entities/Structures/Webbing/webs.yml (100%) rename Resources/Textures/{_EE => _DV}/Mobs/Species/arachne.rsi/meta.json (100%) rename Resources/Textures/{_EE => _DV}/Mobs/Species/arachne.rsi/spider_body.png (100%) rename Resources/Textures/{_EE => _DV}/Mobs/Species/arachne.rsi/spider_body_front.png (100%) rename Resources/Textures/{_EE => _DV}/Mobs/Species/eyes.rsi/eyes.png (100%) rename Resources/Textures/{_EE => _DV}/Mobs/Species/eyes.rsi/meta.json (100%) rename Resources/Textures/{Nyanotrasen => _DV}/Structures/cocoon.rsi/cocoon1.png (100%) rename Resources/Textures/{Nyanotrasen => _DV}/Structures/cocoon.rsi/cocoon2.png (100%) rename Resources/Textures/{Nyanotrasen => _DV}/Structures/cocoon.rsi/cocoon3.png (100%) rename Resources/Textures/{Nyanotrasen => _DV}/Structures/cocoon.rsi/cocoon_large1.png (100%) rename Resources/Textures/{Nyanotrasen => _DV}/Structures/cocoon.rsi/cocoon_large2.png (100%) rename Resources/Textures/{Nyanotrasen => _DV}/Structures/cocoon.rsi/cocoon_large3.png (100%) rename Resources/Textures/{Nyanotrasen => _DV}/Structures/cocoon.rsi/meta.json (100%) diff --git a/Content.Client/_EE/Cocoon/CocoonSystem.cs b/Content.Client/_DV/Cocoon/CocoonSystem.cs similarity index 95% rename from Content.Client/_EE/Cocoon/CocoonSystem.cs rename to Content.Client/_DV/Cocoon/CocoonSystem.cs index f6b66a4b395..85a1fd223a7 100644 --- a/Content.Client/_EE/Cocoon/CocoonSystem.cs +++ b/Content.Client/_DV/Cocoon/CocoonSystem.cs @@ -1,10 +1,10 @@ -using Content.Shared.Cocoon; +using System.Numerics; +using Content.Shared._DV.Cocoon; using Content.Shared.Humanoid; using Robust.Client.GameObjects; using Robust.Shared.Containers; -using System.Numerics; -namespace Content.Client.Cocoon +namespace Content.Client._DV.Cocoon { public sealed class CocoonSystem : EntitySystem { diff --git a/Content.Server/_EE/Cocoon/CocoonerSystem.cs b/Content.Server/_DV/Cocoon/CocoonerSystem.cs similarity index 98% rename from Content.Server/_EE/Cocoon/CocoonerSystem.cs rename to Content.Server/_DV/Cocoon/CocoonerSystem.cs index 9a10d9f5a79..393370cff15 100644 --- a/Content.Server/_EE/Cocoon/CocoonerSystem.cs +++ b/Content.Server/_DV/Cocoon/CocoonerSystem.cs @@ -1,26 +1,26 @@ -using Content.Shared.Cocoon; -using Content.Shared.IdentityManagement; -using Content.Shared.Verbs; -using Content.Shared.DoAfter; -using Content.Shared.Stunnable; -using Content.Shared.Eye.Blinding.Systems; +using Content.Server.DoAfter; +using Content.Server.Popups; +using Content.Server.Speech.Components; +using Content.Shared._DV.Cocoon; +using Content.Shared.Administration.Logs; using Content.Shared.Containers.ItemSlots; using Content.Shared.Damage; -using Content.Shared.Administration.Logs; using Content.Shared.Database; +using Content.Shared.Destructible; +using Content.Shared.DoAfter; +using Content.Shared.Eye.Blinding.Systems; using Content.Shared.Humanoid; -using Content.Server.Popups; -using Content.Server.DoAfter; -using Content.Server.Speech.Components; -using Robust.Shared.Containers; +using Content.Shared.IdentityManagement; using Content.Shared.Mobs.Components; -using Content.Shared.Destructible; -using Robust.Shared.Random; using Content.Shared.Nutrition.Components; using Content.Shared.Storage; +using Content.Shared.Stunnable; +using Content.Shared.Verbs; +using Robust.Shared.Containers; +using Robust.Shared.Random; using Robust.Shared.Utility; -namespace Content.Server.Cocoon +namespace Content.Server._DV.Cocoon { public sealed class CocooningSystem : EntitySystem { diff --git a/Content.Server/_EE/Vampire/BloodSuckedComponent.cs b/Content.Server/_DV/Vampire/BloodSuckedComponent.cs similarity index 82% rename from Content.Server/_EE/Vampire/BloodSuckedComponent.cs rename to Content.Server/_DV/Vampire/BloodSuckedComponent.cs index df0eb4e3d65..a86191b434c 100644 --- a/Content.Server/_EE/Vampire/BloodSuckedComponent.cs +++ b/Content.Server/_DV/Vampire/BloodSuckedComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Server.Vampire +namespace Content.Server._DV.Vampire { /// /// For entities who have been sucked. diff --git a/Content.Server/_EE/Vampire/BloodSuckerComponent.cs b/Content.Server/_DV/Vampire/BloodSuckerComponent.cs similarity index 97% rename from Content.Server/_EE/Vampire/BloodSuckerComponent.cs rename to Content.Server/_DV/Vampire/BloodSuckerComponent.cs index e7bd70f91c5..80e5d9502f8 100644 --- a/Content.Server/_EE/Vampire/BloodSuckerComponent.cs +++ b/Content.Server/_DV/Vampire/BloodSuckerComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Server.Vampire +namespace Content.Server._DV.Vampire { [RegisterComponent] public sealed partial class BloodSuckerComponent : Component diff --git a/Content.Server/_EE/Vampire/BloodSuckerSystem.cs b/Content.Server/_DV/Vampire/BloodSuckerSystem.cs similarity index 98% rename from Content.Server/_EE/Vampire/BloodSuckerSystem.cs rename to Content.Server/_DV/Vampire/BloodSuckerSystem.cs index 182a29f74ca..8465c85baf9 100644 --- a/Content.Server/_EE/Vampire/BloodSuckerSystem.cs +++ b/Content.Server/_DV/Vampire/BloodSuckerSystem.cs @@ -1,26 +1,26 @@ using System.Linq; -using Content.Shared.Verbs; -using Content.Shared.Damage; -using Content.Shared.DoAfter; -using Content.Shared.Damage.Prototypes; -using Content.Shared.Interaction; -using Content.Shared.Inventory; -using Content.Shared.Administration.Logs; -using Content.Shared.Vampiric; -using Content.Shared.Cocoon; using Content.Server.Atmos.Components; using Content.Server.Body.Components; using Content.Server.Body.Systems; -using Content.Shared.Chemistry.EntitySystems; -using Content.Server.Popups; using Content.Server.DoAfter; using Content.Server.Nutrition.Components; +using Content.Server.Popups; +using Content.Shared._DV.Cocoon; +using Content.Shared._DV.Vampiric; +using Content.Shared.Administration.Logs; +using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.Damage; +using Content.Shared.Damage.Prototypes; +using Content.Shared.DoAfter; using Content.Shared.HealthExaminable; -using Robust.Shared.Prototypes; +using Content.Shared.Interaction; +using Content.Shared.Inventory; +using Content.Shared.Verbs; using Robust.Shared.Audio.Systems; +using Robust.Shared.Prototypes; using Robust.Shared.Utility; -namespace Content.Server.Vampire +namespace Content.Server._DV.Vampire { public sealed class BloodSuckerSystem : EntitySystem { diff --git a/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs b/Content.Server/_DV/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs similarity index 92% rename from Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs rename to Content.Server/_DV/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs index 1a3c9b1588a..728618a1690 100644 --- a/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs +++ b/Content.Server/_DV/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Server.Vampiric +namespace Content.Server._DV.Vampire.Injector { [RegisterComponent] /// diff --git a/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs b/Content.Server/_DV/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs similarity index 95% rename from Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs rename to Content.Server/_DV/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs index 480c60218a8..8f1a721093a 100644 --- a/Content.Server/_EE/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs +++ b/Content.Server/_DV/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs @@ -1,8 +1,7 @@ using Content.Server.Popups; -using Content.Server.Vampiric; using Content.Shared.Interaction; -namespace Content.Server.Vampire +namespace Content.Server._DV.Vampire.Injector { public sealed class BloodSuckerGlandInjectorSystem : EntitySystem { diff --git a/Content.Shared/_EE/Cocoon/CocoonComponent.cs b/Content.Shared/_DV/Cocoon/CocoonComponent.cs similarity index 87% rename from Content.Shared/_EE/Cocoon/CocoonComponent.cs rename to Content.Shared/_DV/Cocoon/CocoonComponent.cs index 66ba6e6dd37..c887a2e5633 100644 --- a/Content.Shared/_EE/Cocoon/CocoonComponent.cs +++ b/Content.Shared/_DV/Cocoon/CocoonComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Shared.Cocoon +namespace Content.Shared._DV.Cocoon { [RegisterComponent] public sealed partial class CocoonComponent : Component diff --git a/Content.Shared/_EE/Cocoon/CocoonDoAfterEvent.cs b/Content.Shared/_DV/Cocoon/CocoonDoAfterEvent.cs similarity index 89% rename from Content.Shared/_EE/Cocoon/CocoonDoAfterEvent.cs rename to Content.Shared/_DV/Cocoon/CocoonDoAfterEvent.cs index 0b9049e9890..3bfde77a647 100644 --- a/Content.Shared/_EE/Cocoon/CocoonDoAfterEvent.cs +++ b/Content.Shared/_DV/Cocoon/CocoonDoAfterEvent.cs @@ -1,7 +1,7 @@ -using Robust.Shared.Serialization; using Content.Shared.DoAfter; +using Robust.Shared.Serialization; -namespace Content.Shared.Cocoon +namespace Content.Shared._DV.Cocoon { [Serializable, NetSerializable] public sealed partial class CocoonDoAfterEvent : SimpleDoAfterEvent diff --git a/Content.Shared/_EE/Cocoon/CocoonerComponent.cs b/Content.Shared/_DV/Cocoon/CocoonerComponent.cs similarity index 90% rename from Content.Shared/_EE/Cocoon/CocoonerComponent.cs rename to Content.Shared/_DV/Cocoon/CocoonerComponent.cs index 17cce973096..aba674fb80f 100644 --- a/Content.Shared/_EE/Cocoon/CocoonerComponent.cs +++ b/Content.Shared/_DV/Cocoon/CocoonerComponent.cs @@ -1,6 +1,6 @@ using Robust.Shared.GameStates; -namespace Content.Shared.Cocoon +namespace Content.Shared._DV.Cocoon { [RegisterComponent, NetworkedComponent] public sealed partial class CocoonerComponent : Component diff --git a/Content.Shared/_EE/Vampiric/BloodSuckDoAfterEvent.cs b/Content.Shared/_DV/Vampiric/BloodSuckDoAfterEvent.cs similarity index 83% rename from Content.Shared/_EE/Vampiric/BloodSuckDoAfterEvent.cs rename to Content.Shared/_DV/Vampiric/BloodSuckDoAfterEvent.cs index 6aadc258d73..bc780a96298 100644 --- a/Content.Shared/_EE/Vampiric/BloodSuckDoAfterEvent.cs +++ b/Content.Shared/_DV/Vampiric/BloodSuckDoAfterEvent.cs @@ -1,7 +1,7 @@ -using Robust.Shared.Serialization; using Content.Shared.DoAfter; +using Robust.Shared.Serialization; -namespace Content.Shared.Vampiric +namespace Content.Shared._DV.Vampiric { [Serializable, NetSerializable] public sealed partial class BloodSuckDoAfterEvent : SimpleDoAfterEvent diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Mechanisms/vampiric.yml b/Resources/Prototypes/_DV/Entities/Body/Mechanisms/vampiric.yml similarity index 100% rename from Resources/Prototypes/Nyanotrasen/Entities/Body/Mechanisms/vampiric.yml rename to Resources/Prototypes/_DV/Entities/Body/Mechanisms/vampiric.yml diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml b/Resources/Prototypes/_DV/Entities/Body/Parts/spider.yml similarity index 100% rename from Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml rename to Resources/Prototypes/_DV/Entities/Body/Parts/spider.yml diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml b/Resources/Prototypes/_DV/Entities/Body/Prototypes/arachne.yml similarity index 100% rename from Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml rename to Resources/Prototypes/_DV/Entities/Body/Prototypes/arachne.yml diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/vampiricanimal.yml b/Resources/Prototypes/_DV/Entities/Body/Prototypes/vampiricanimal.yml similarity index 100% rename from Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/vampiricanimal.yml rename to Resources/Prototypes/_DV/Entities/Body/Prototypes/vampiricanimal.yml diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Structures/Webbing/webs.yml b/Resources/Prototypes/_DV/Entities/Structures/Webbing/webs.yml similarity index 100% rename from Resources/Prototypes/Nyanotrasen/Entities/Structures/Webbing/webs.yml rename to Resources/Prototypes/_DV/Entities/Structures/Webbing/webs.yml diff --git a/Resources/Textures/_EE/Mobs/Species/arachne.rsi/meta.json b/Resources/Textures/_DV/Mobs/Species/arachne.rsi/meta.json similarity index 100% rename from Resources/Textures/_EE/Mobs/Species/arachne.rsi/meta.json rename to Resources/Textures/_DV/Mobs/Species/arachne.rsi/meta.json diff --git a/Resources/Textures/_EE/Mobs/Species/arachne.rsi/spider_body.png b/Resources/Textures/_DV/Mobs/Species/arachne.rsi/spider_body.png similarity index 100% rename from Resources/Textures/_EE/Mobs/Species/arachne.rsi/spider_body.png rename to Resources/Textures/_DV/Mobs/Species/arachne.rsi/spider_body.png diff --git a/Resources/Textures/_EE/Mobs/Species/arachne.rsi/spider_body_front.png b/Resources/Textures/_DV/Mobs/Species/arachne.rsi/spider_body_front.png similarity index 100% rename from Resources/Textures/_EE/Mobs/Species/arachne.rsi/spider_body_front.png rename to Resources/Textures/_DV/Mobs/Species/arachne.rsi/spider_body_front.png diff --git a/Resources/Textures/_EE/Mobs/Species/eyes.rsi/eyes.png b/Resources/Textures/_DV/Mobs/Species/eyes.rsi/eyes.png similarity index 100% rename from Resources/Textures/_EE/Mobs/Species/eyes.rsi/eyes.png rename to Resources/Textures/_DV/Mobs/Species/eyes.rsi/eyes.png diff --git a/Resources/Textures/_EE/Mobs/Species/eyes.rsi/meta.json b/Resources/Textures/_DV/Mobs/Species/eyes.rsi/meta.json similarity index 100% rename from Resources/Textures/_EE/Mobs/Species/eyes.rsi/meta.json rename to Resources/Textures/_DV/Mobs/Species/eyes.rsi/meta.json diff --git a/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon1.png b/Resources/Textures/_DV/Structures/cocoon.rsi/cocoon1.png similarity index 100% rename from Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon1.png rename to Resources/Textures/_DV/Structures/cocoon.rsi/cocoon1.png diff --git a/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon2.png b/Resources/Textures/_DV/Structures/cocoon.rsi/cocoon2.png similarity index 100% rename from Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon2.png rename to Resources/Textures/_DV/Structures/cocoon.rsi/cocoon2.png diff --git a/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon3.png b/Resources/Textures/_DV/Structures/cocoon.rsi/cocoon3.png similarity index 100% rename from Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon3.png rename to Resources/Textures/_DV/Structures/cocoon.rsi/cocoon3.png diff --git a/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large1.png b/Resources/Textures/_DV/Structures/cocoon.rsi/cocoon_large1.png similarity index 100% rename from Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large1.png rename to Resources/Textures/_DV/Structures/cocoon.rsi/cocoon_large1.png diff --git a/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large2.png b/Resources/Textures/_DV/Structures/cocoon.rsi/cocoon_large2.png similarity index 100% rename from Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large2.png rename to Resources/Textures/_DV/Structures/cocoon.rsi/cocoon_large2.png diff --git a/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large3.png b/Resources/Textures/_DV/Structures/cocoon.rsi/cocoon_large3.png similarity index 100% rename from Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large3.png rename to Resources/Textures/_DV/Structures/cocoon.rsi/cocoon_large3.png diff --git a/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/meta.json b/Resources/Textures/_DV/Structures/cocoon.rsi/meta.json similarity index 100% rename from Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/meta.json rename to Resources/Textures/_DV/Structures/cocoon.rsi/meta.json From 23709c79ea658314f99fbaf6871dd5dbe16de045 Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Thu, 30 Jan 2025 14:27:59 -0500 Subject: [PATCH 17/26] migrate namespace 2 --- Resources/Locale/en-US/{_EE => _DV}/abilities/arachne.ftl | 0 .../Locale/en-US/{_EE => _DV}/abilities/bloodsucker.ftl | 0 Resources/Locale/en-US/_DV/abilities/chitinid.ftl | 1 - Resources/Locale/en-US/_DV/abilities/item-cougher.ftl | 1 - Resources/Locale/en-US/_DV/abilities/lifedrainer.ftl | 5 ----- .../en-US/{_EE => _DV}/metabolism/metabolizer-types.ftl | 0 Resources/Locale/en-US/_DV/species/species.ftl | 1 + Resources/Locale/en-US/_EE/species/species.ftl | 3 --- .../Prototypes/{_EE => _DV}/Chemistry/metabolizer_types.yml | 0 Resources/Prototypes/{_EE => _DV}/Species/arachne.yml | 0 Resources/Prototypes/_EE/GameRules/events.yml | 0 11 files changed, 1 insertion(+), 10 deletions(-) rename Resources/Locale/en-US/{_EE => _DV}/abilities/arachne.ftl (100%) rename Resources/Locale/en-US/{_EE => _DV}/abilities/bloodsucker.ftl (100%) rename Resources/Locale/en-US/{_EE => _DV}/metabolism/metabolizer-types.ftl (100%) delete mode 100644 Resources/Locale/en-US/_EE/species/species.ftl rename Resources/Prototypes/{_EE => _DV}/Chemistry/metabolizer_types.yml (100%) rename Resources/Prototypes/{_EE => _DV}/Species/arachne.yml (100%) delete mode 100644 Resources/Prototypes/_EE/GameRules/events.yml diff --git a/Resources/Locale/en-US/_EE/abilities/arachne.ftl b/Resources/Locale/en-US/_DV/abilities/arachne.ftl similarity index 100% rename from Resources/Locale/en-US/_EE/abilities/arachne.ftl rename to Resources/Locale/en-US/_DV/abilities/arachne.ftl diff --git a/Resources/Locale/en-US/_EE/abilities/bloodsucker.ftl b/Resources/Locale/en-US/_DV/abilities/bloodsucker.ftl similarity index 100% rename from Resources/Locale/en-US/_EE/abilities/bloodsucker.ftl rename to Resources/Locale/en-US/_DV/abilities/bloodsucker.ftl diff --git a/Resources/Locale/en-US/_DV/abilities/chitinid.ftl b/Resources/Locale/en-US/_DV/abilities/chitinid.ftl index 87759da4f7c..e69de29bb2d 100644 --- a/Resources/Locale/en-US/_DV/abilities/chitinid.ftl +++ b/Resources/Locale/en-US/_DV/abilities/chitinid.ftl @@ -1 +0,0 @@ -chitzite-cough = {CAPITALIZE(THE($name))} starts coughing up a hunk of Chitzite! diff --git a/Resources/Locale/en-US/_DV/abilities/item-cougher.ftl b/Resources/Locale/en-US/_DV/abilities/item-cougher.ftl index 56d80b02f2f..e69de29bb2d 100644 --- a/Resources/Locale/en-US/_DV/abilities/item-cougher.ftl +++ b/Resources/Locale/en-US/_DV/abilities/item-cougher.ftl @@ -1 +0,0 @@ -item-cougher-mask = Take off your {$mask} first. diff --git a/Resources/Locale/en-US/_DV/abilities/lifedrainer.ftl b/Resources/Locale/en-US/_DV/abilities/lifedrainer.ftl index 4072129ab0f..e69de29bb2d 100644 --- a/Resources/Locale/en-US/_DV/abilities/lifedrainer.ftl +++ b/Resources/Locale/en-US/_DV/abilities/lifedrainer.ftl @@ -1,5 +0,0 @@ -verb-life-drain = Life drain -life-drain-second-start = {CAPITALIZE(THE($drainer))} starts draining your life force! -life-drain-third-start = {CAPITALIZE(THE($drainer))} starts draining {THE($target)}'s life force! -life-drain-second-end = Your being is annihilated. -life-drain-third-end = {CAPITALIZE(THE($drainer))} drains {THE($target)}'s life force! diff --git a/Resources/Locale/en-US/_EE/metabolism/metabolizer-types.ftl b/Resources/Locale/en-US/_DV/metabolism/metabolizer-types.ftl similarity index 100% rename from Resources/Locale/en-US/_EE/metabolism/metabolizer-types.ftl rename to Resources/Locale/en-US/_DV/metabolism/metabolizer-types.ftl diff --git a/Resources/Locale/en-US/_DV/species/species.ftl b/Resources/Locale/en-US/_DV/species/species.ftl index b8cebd93d58..30ef56ba786 100644 --- a/Resources/Locale/en-US/_DV/species/species.ftl +++ b/Resources/Locale/en-US/_DV/species/species.ftl @@ -4,3 +4,4 @@ species-name-vulpkanin = Vulpkanin species-name-harpy = Harpy species-name-rodentia = Rodentia species-name-chitinid = Chitinid +species-name-arachne = Arachne diff --git a/Resources/Locale/en-US/_EE/species/species.ftl b/Resources/Locale/en-US/_EE/species/species.ftl deleted file mode 100644 index 174ce96112c..00000000000 --- a/Resources/Locale/en-US/_EE/species/species.ftl +++ /dev/null @@ -1,3 +0,0 @@ -## Species Names - -species-name-arachne = Arachne diff --git a/Resources/Prototypes/_EE/Chemistry/metabolizer_types.yml b/Resources/Prototypes/_DV/Chemistry/metabolizer_types.yml similarity index 100% rename from Resources/Prototypes/_EE/Chemistry/metabolizer_types.yml rename to Resources/Prototypes/_DV/Chemistry/metabolizer_types.yml diff --git a/Resources/Prototypes/_EE/Species/arachne.yml b/Resources/Prototypes/_DV/Species/arachne.yml similarity index 100% rename from Resources/Prototypes/_EE/Species/arachne.yml rename to Resources/Prototypes/_DV/Species/arachne.yml diff --git a/Resources/Prototypes/_EE/GameRules/events.yml b/Resources/Prototypes/_EE/GameRules/events.yml deleted file mode 100644 index e69de29bb2d..00000000000 From b9f6e70264eba7aeb9415bbbb3f2d378148c2a20 Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Thu, 30 Jan 2025 14:31:28 -0500 Subject: [PATCH 18/26] namespace 3 --- .../Prototypes/_DV/Entities/Mobs/Species/arachne.yml | 12 ++++++------ Resources/Prototypes/_DV/tags.yml | 8 +++++++- Resources/Prototypes/_EE/tag.yml | 5 ----- 3 files changed, 13 insertions(+), 12 deletions(-) delete mode 100644 Resources/Prototypes/_EE/tag.yml diff --git a/Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml b/Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml index 018c61c1824..d02cb49d60a 100644 --- a/Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml +++ b/Resources/Prototypes/_DV/Entities/Mobs/Species/arachne.yml @@ -9,14 +9,14 @@ # Arachne are one of the species that needs a manual visual layers setup. layers: - map: [ "enum.HumanoidVisualLayers.LLeg" ] - sprite: _EE/Mobs/Species/arachne.rsi + sprite: _DV/Mobs/Species/arachne.rsi state: spider_body - map: [ "enum.HumanoidVisualLayers.Chest" ] color: "#e8b59b" sprite: Mobs/Species/Human/parts.rsi state: torso_m - map: [ "enum.HumanoidVisualLayers.RLeg" ] - sprite: _EE/Mobs/Species/arachne.rsi + sprite: _DV/Mobs/Species/arachne.rsi state: spider_body_front - map: [ "enum.HumanoidVisualLayers.Head" ] color: "#e8b59b" @@ -24,7 +24,7 @@ state: head_m - map: [ "enum.HumanoidVisualLayers.Eyes" ] color: "#008800" - sprite: _EE/Mobs/Species/eyes.rsi + sprite: _DV/Mobs/Species/eyes.rsi state: eyes - map: [ "enum.HumanoidVisualLayers.RArm" ] color: "#e8b59b" @@ -163,14 +163,14 @@ - type: Sprite layers: - map: [ "enum.HumanoidVisualLayers.LLeg" ] - sprite: _EE/Mobs/Species/arachne.rsi + sprite: _DV/Mobs/Species/arachne.rsi state: spider_body - map: [ "enum.HumanoidVisualLayers.Chest" ] color: "#e8b59b" sprite: Mobs/Species/Human/parts.rsi state: torso_m - map: [ "enum.HumanoidVisualLayers.RLeg" ] - sprite: _EE/Mobs/Species/arachne.rsi + sprite: _DV/Mobs/Species/arachne.rsi state: spider_body_front - map: [ "enum.HumanoidVisualLayers.Head" ] color: "#e8b59b" @@ -178,7 +178,7 @@ state: head_m - map: [ "enum.HumanoidVisualLayers.Eyes" ] color: "#008800" - sprite: _EE/Mobs/Species/eyes.rsi + sprite: _DV/Mobs/Species/eyes.rsi state: eyes - map: [ "enum.HumanoidVisualLayers.RArm" ] color: "#e8b59b" diff --git a/Resources/Prototypes/_DV/tags.yml b/Resources/Prototypes/_DV/tags.yml index 76b96a7595e..2439bb8bd76 100644 --- a/Resources/Prototypes/_DV/tags.yml +++ b/Resources/Prototypes/_DV/tags.yml @@ -68,7 +68,7 @@ - type: Tag id: HidesHarpyWings - + - type: Tag id: HudMedicalSecurity #Craftable Corpsman Glasses @@ -107,3 +107,9 @@ - type: Tag id: PermissibleForSurgery # Can be worn on the body during surgery + +- type: Tag # Arachne port + id: ArachneWeb + +- type: Tag # Arachne port + id: Oneirophage diff --git a/Resources/Prototypes/_EE/tag.yml b/Resources/Prototypes/_EE/tag.yml deleted file mode 100644 index 1a468429c1b..00000000000 --- a/Resources/Prototypes/_EE/tag.yml +++ /dev/null @@ -1,5 +0,0 @@ -- type: Tag # EE - id: ArachneWeb - -- type: Tag # EE - id: Oneirophage From 0bf7c9bf13a07a0199f4a2640424aa529a4d53a9 Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Thu, 30 Jan 2025 14:35:48 -0500 Subject: [PATCH 19/26] namespace 4 real --- Resources/Prototypes/_DV/Entities/Structures/Webbing/webs.yml | 4 ++-- Resources/Prototypes/_DV/Species/arachne.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Resources/Prototypes/_DV/Entities/Structures/Webbing/webs.yml b/Resources/Prototypes/_DV/Entities/Structures/Webbing/webs.yml index e4a3aee793f..67b76ba1e73 100644 --- a/Resources/Prototypes/_DV/Entities/Structures/Webbing/webs.yml +++ b/Resources/Prototypes/_DV/Entities/Structures/Webbing/webs.yml @@ -9,7 +9,7 @@ components: - type: Sprite layers: - - sprite: Nyanotrasen/Structures/cocoon.rsi + - sprite: _DV/Structures/cocoon.rsi state: cocoon_large1 map: [ "enum.DamageStateVisualLayers.Base" ] - type: RandomSprite @@ -80,7 +80,7 @@ components: - type: Sprite layers: - - sprite: Nyanotrasen/Structures/cocoon.rsi + - sprite: _DV/Structures/cocoon.rsi state: cocoon1 map: [ "enum.DamageStateVisualLayers.Base" ] - type: RandomSprite diff --git a/Resources/Prototypes/_DV/Species/arachne.yml b/Resources/Prototypes/_DV/Species/arachne.yml index f74cba57dfe..41af08c9400 100644 --- a/Resources/Prototypes/_DV/Species/arachne.yml +++ b/Resources/Prototypes/_DV/Species/arachne.yml @@ -52,5 +52,5 @@ - type: humanoidBaseSprite id: MobArachneEyes baseSprite: - sprite: _EE/Mobs/Species/eyes.rsi + sprite: _DV/Mobs/Species/eyes.rsi state: eyes From 060381166c16445e14edccdcf4c27804c3567a2a Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Fri, 31 Jan 2025 09:50:40 -0500 Subject: [PATCH 20/26] Update chitinid.ftl Signed-off-by: Lyndomen <49795619+Lyndomen@users.noreply.github.com> --- Resources/Locale/en-US/_DV/abilities/chitinid.ftl | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Locale/en-US/_DV/abilities/chitinid.ftl b/Resources/Locale/en-US/_DV/abilities/chitinid.ftl index e69de29bb2d..58c88203d8c 100644 --- a/Resources/Locale/en-US/_DV/abilities/chitinid.ftl +++ b/Resources/Locale/en-US/_DV/abilities/chitinid.ftl @@ -0,0 +1 @@ +chitzite-cough = {CAPITALIZE(THE($name))} starts coughing up a hunk of Chitzite! From 136e70163d80cc5b89f8eb38d6ee94e71aee25bb Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Fri, 31 Jan 2025 09:51:00 -0500 Subject: [PATCH 21/26] Update item-cougher.ftl Signed-off-by: Lyndomen <49795619+Lyndomen@users.noreply.github.com> --- Resources/Locale/en-US/_DV/abilities/item-cougher.ftl | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Locale/en-US/_DV/abilities/item-cougher.ftl b/Resources/Locale/en-US/_DV/abilities/item-cougher.ftl index e69de29bb2d..6183a4cd135 100644 --- a/Resources/Locale/en-US/_DV/abilities/item-cougher.ftl +++ b/Resources/Locale/en-US/_DV/abilities/item-cougher.ftl @@ -0,0 +1 @@ +item-cougher-mask = Take off your {$mask} first. From 22ba57ab2fab9bd9dad1b30a07b74db5077bde6a Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Fri, 31 Jan 2025 09:51:52 -0500 Subject: [PATCH 22/26] Update lifedrainer.ftl Signed-off-by: Lyndomen <49795619+Lyndomen@users.noreply.github.com> --- Resources/Locale/en-US/_DV/abilities/lifedrainer.ftl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Resources/Locale/en-US/_DV/abilities/lifedrainer.ftl b/Resources/Locale/en-US/_DV/abilities/lifedrainer.ftl index e69de29bb2d..d039253c581 100644 --- a/Resources/Locale/en-US/_DV/abilities/lifedrainer.ftl +++ b/Resources/Locale/en-US/_DV/abilities/lifedrainer.ftl @@ -0,0 +1,5 @@ +verb-life-drain = Life drain +life-drain-second-start = {CAPITALIZE(THE($drainer))} starts draining your life force! +life-drain-third-start = {CAPITALIZE(THE($drainer))} starts draining {THE($target)}'s life force! +life-drain-second-end = Your being is annihilated. +life-drain-third-end = {CAPITALIZE(THE($drainer))} drains {THE($target)}'s life force! From ba0707dbe8582ab9c02d651959f61e6ae035fa19 Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Fri, 31 Jan 2025 13:47:31 -0500 Subject: [PATCH 23/26] move to shared gaming --- Content.Server/_DV/Cocoon/CocoonerSystem.cs | 140 ------------ .../_DV/Vampire/BloodSuckerSystem.cs | 13 +- Content.Shared/_DV/Cocoon/CocoonerSystem.cs | 169 +++++++++++++++ .../_DV/Vampire/BloodSuckedComponent.cs | 2 +- .../_DV/Vampire/BloodSuckerComponent.cs | 2 +- .../_DV/Vampire/BloodSuckerSystem.cs | 199 ++++++++++++++++++ .../BloodSuckerGlandInjectorComponent.cs | 2 +- .../BloodSuckerGlandInjectorSystem.cs | 3 +- 8 files changed, 379 insertions(+), 151 deletions(-) create mode 100644 Content.Shared/_DV/Cocoon/CocoonerSystem.cs rename {Content.Server => Content.Shared}/_DV/Vampire/BloodSuckedComponent.cs (82%) rename {Content.Server => Content.Shared}/_DV/Vampire/BloodSuckerComponent.cs (97%) create mode 100644 Content.Shared/_DV/Vampire/BloodSuckerSystem.cs rename {Content.Server => Content.Shared}/_DV/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs (92%) rename {Content.Server => Content.Shared}/_DV/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs (94%) diff --git a/Content.Server/_DV/Cocoon/CocoonerSystem.cs b/Content.Server/_DV/Cocoon/CocoonerSystem.cs index 393370cff15..f444e6bf479 100644 --- a/Content.Server/_DV/Cocoon/CocoonerSystem.cs +++ b/Content.Server/_DV/Cocoon/CocoonerSystem.cs @@ -5,20 +5,11 @@ using Content.Shared.Administration.Logs; using Content.Shared.Containers.ItemSlots; using Content.Shared.Damage; -using Content.Shared.Database; using Content.Shared.Destructible; -using Content.Shared.DoAfter; using Content.Shared.Eye.Blinding.Systems; -using Content.Shared.Humanoid; -using Content.Shared.IdentityManagement; -using Content.Shared.Mobs.Components; -using Content.Shared.Nutrition.Components; -using Content.Shared.Storage; using Content.Shared.Stunnable; -using Content.Shared.Verbs; using Robust.Shared.Containers; using Robust.Shared.Random; -using Robust.Shared.Utility; namespace Content.Server._DV.Cocoon { @@ -38,54 +29,8 @@ public sealed class CocooningSystem : EntitySystem public override void Initialize() { base.Initialize(); - SubscribeLocalEvent>(AddVerbs); SubscribeLocalEvent(OnCocEntInserted); SubscribeLocalEvent(OnCocEntRemoved); - SubscribeLocalEvent(OnDamageChanged); - SubscribeLocalEvent(OnCocoonDoAfter); - SubscribeLocalEvent(OnUnCocoonDoAfter); - } - - private void AddVerbs(EntityUid uid, CocoonerComponent component, GetVerbsEvent args) - { - AddCocoonVerb(uid, component, args); - AddUnCocoonVerb(uid, component, args); - } - - private void AddCocoonVerb(EntityUid uid, CocoonerComponent component, GetVerbsEvent args) - { - if (!args.CanAccess || !args.CanInteract || !HasComp(args.Target) || args.Target == args.User) - return; - - InnateVerb verb = new() - { - Act = () => - { - StartCocooning(uid, component, args.Target); - }, - Text = Loc.GetString("cocoon"), - Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/Actions/web.png")), - Priority = 2 - }; - args.Verbs.Add(verb); - } - - private void AddUnCocoonVerb(EntityUid uid, CocoonerComponent component, GetVerbsEvent args) - { - if (!args.CanAccess || !args.CanInteract || !HasComp(args.Target)) - return; - - InnateVerb verb = new() - { - Act = () => - { - StartUnCocooning(uid, component, args.Target); - }, - Text = Loc.GetString("uncocoon"), - Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/Actions/web.png")), - Priority = 2 - }; - args.Verbs.Add(verb); } private void OnCocEntInserted(EntityUid uid, CocoonComponent component, EntInsertedIntoContainerMessage args) @@ -113,90 +58,5 @@ private void OnCocEntRemoved(EntityUid uid, CocoonComponent component, EntRemove RemComp(args.Entity); _blindableSystem.UpdateIsBlind(args.Entity); } - - private void OnDamageChanged(EntityUid uid, CocoonComponent component, DamageChangedEvent args) - { - if (!args.DamageIncreased || args.DamageDelta == null || component.Victim == null) - return; - - var damage = args.DamageDelta * component.DamagePassthrough; - _damageableSystem.TryChangeDamage(component.Victim, damage); - } - - private void StartCocooning(EntityUid uid, CocoonerComponent component, EntityUid target) - { - _popupSystem.PopupEntity(Loc.GetString("cocoon-start-third-person", ("target", Identity.Entity(target, EntityManager)), ("spider", Identity.Entity(uid, EntityManager))), uid, - Shared.Popups.PopupType.MediumCaution); - - var delay = component.CocoonDelay; - - if (HasComp(target)) - delay *= component.CocoonKnockdownMultiplier; - - var args = new DoAfterArgs(EntityManager, uid, delay, new CocoonDoAfterEvent(), uid, target: target) - { - BreakOnMove = true - }; - - _doAfter.TryStartDoAfter(args); - } - - private void StartUnCocooning(EntityUid uid, CocoonerComponent component, EntityUid target) - { - _popupSystem.PopupEntity(Loc.GetString("uncocoon-start-third-person", ("target", target), ("spider", Identity.Entity(uid, EntityManager))), uid, - Shared.Popups.PopupType.MediumCaution); - - var delay = component.CocoonDelay / 2; - - var args = new DoAfterArgs(EntityManager, uid, delay, new UnCocoonDoAfterEvent(), uid, target: target) - { - BreakOnMove = true - }; - - _doAfter.TryStartDoAfter(args); - } - - private void OnCocoonDoAfter(EntityUid uid, CocoonerComponent component, CocoonDoAfterEvent args) - { - if (args.Handled || args.Cancelled || args.Args.Target == null) - return; - - var spawnProto = HasComp(args.Args.Target) ? "CocoonedHumanoid" : "CocoonSmall"; - Transform(args.Args.Target.Value).AttachToGridOrMap(); - var cocoon = Spawn(spawnProto, Transform(args.Args.Target.Value).Coordinates); - - if (!TryComp(cocoon, out var slots)) - return; - - _itemSlots.SetLock(cocoon, BodySlot, false, slots); - _itemSlots.TryInsert(cocoon, BodySlot, args.Args.Target.Value, args.Args.User); - _itemSlots.SetLock(cocoon, BodySlot, true, slots); - - var impact = (spawnProto == "CocoonedHumanoid") ? LogImpact.High : LogImpact.Medium; - - _adminLogger.Add(LogType.Action, impact, $"{ToPrettyString(args.Args.User):player} cocooned {ToPrettyString(args.Args.Target.Value):target}"); - args.Handled = true; - } - - private void OnUnCocoonDoAfter(EntityUid uid, CocoonerComponent component, UnCocoonDoAfterEvent args) - { - if (args.Handled || args.Cancelled || args.Args.Target == null) - return; - - if (TryComp(args.Args.Target.Value, out var butcher)) - { - var spawnEntities = EntitySpawnCollection.GetSpawns(butcher.SpawnedEntities, _robustRandom); - var coords = Transform(args.Args.Target.Value).MapPosition; - EntityUid popupEnt = default!; - foreach (var proto in spawnEntities) - popupEnt = Spawn(proto, coords.Offset(_robustRandom.NextVector2(0.25f))); - } - - _destructibleSystem.DestroyEntity(args.Args.Target.Value); - - _adminLogger.Add(LogType.Action, LogImpact.Low - , $"{ToPrettyString(args.Args.User):player} uncocooned {ToPrettyString(args.Args.Target.Value):target}"); - args.Handled = true; - } } } diff --git a/Content.Server/_DV/Vampire/BloodSuckerSystem.cs b/Content.Server/_DV/Vampire/BloodSuckerSystem.cs index 8465c85baf9..fd8095d0da7 100644 --- a/Content.Server/_DV/Vampire/BloodSuckerSystem.cs +++ b/Content.Server/_DV/Vampire/BloodSuckerSystem.cs @@ -1,13 +1,13 @@ -using System.Linq; +using System.Linq; using Content.Server.Atmos.Components; using Content.Server.Body.Components; using Content.Server.Body.Systems; -using Content.Server.DoAfter; using Content.Server.Nutrition.Components; -using Content.Server.Popups; using Content.Shared._DV.Cocoon; +using Content.Shared._DV.Vampire; using Content.Shared._DV.Vampiric; using Content.Shared.Administration.Logs; +using Content.Shared.Body.Systems; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Damage; using Content.Shared.Damage.Prototypes; @@ -15,6 +15,7 @@ using Content.Shared.HealthExaminable; using Content.Shared.Interaction; using Content.Shared.Inventory; +using Content.Shared.Popups; using Content.Shared.Verbs; using Robust.Shared.Audio.Systems; using Robust.Shared.Prototypes; @@ -24,10 +25,10 @@ namespace Content.Server._DV.Vampire { public sealed class BloodSuckerSystem : EntitySystem { - [Dependency] private readonly BodySystem _bodySystem = default!; + [Dependency] private readonly SharedBodySystem _bodySystem = default!; [Dependency] private readonly SharedSolutionContainerSystem _solutionSystem = default!; - [Dependency] private readonly PopupSystem _popups = default!; - [Dependency] private readonly DoAfterSystem _doAfter = default!; + [Dependency] private readonly SharedPopupSystem _popups = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly StomachSystem _stomachSystem = default!; [Dependency] private readonly DamageableSystem _damageableSystem = default!; diff --git a/Content.Shared/_DV/Cocoon/CocoonerSystem.cs b/Content.Shared/_DV/Cocoon/CocoonerSystem.cs new file mode 100644 index 00000000000..e4f485b5cb5 --- /dev/null +++ b/Content.Shared/_DV/Cocoon/CocoonerSystem.cs @@ -0,0 +1,169 @@ +using Content.Shared.Administration.Logs; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Damage; +using Content.Shared.Database; +using Content.Shared.Destructible; +using Content.Shared.DoAfter; +using Content.Shared.Humanoid; +using Content.Shared.IdentityManagement; +using Content.Shared.Mobs.Components; +using Content.Shared.Nutrition.Components; +using Content.Shared.Popups; +using Content.Shared.Storage; +using Content.Shared.Stunnable; +using Content.Shared.Verbs; +using Robust.Shared.Random; +using Robust.Shared.Utility; + +namespace Content.Shared._DV.Cocoon +{ + public sealed class CocooningSystem : EntitySystem + { + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; + [Dependency] private readonly ItemSlotsSystem _itemSlots = default!; + [Dependency] private readonly DamageableSystem _damageableSystem = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly SharedDestructibleSystem _destructibleSystem = default!; + [Dependency] private readonly IRobustRandom _robustRandom = default!; + + private const string BodySlot = "body_slot"; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent>(AddVerbs); + SubscribeLocalEvent(OnDamageChanged); + SubscribeLocalEvent(OnCocoonDoAfter); + SubscribeLocalEvent(OnUnCocoonDoAfter); + } + + private void AddVerbs(EntityUid uid, CocoonerComponent component, GetVerbsEvent args) + { + AddCocoonVerb(uid, component, args); + AddUnCocoonVerb(uid, component, args); + } + + private void AddCocoonVerb(EntityUid uid, CocoonerComponent component, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract || !HasComp(args.Target) || args.Target == args.User) + return; + + InnateVerb verb = new() + { + Act = () => + { + StartCocooning(uid, component, args.Target); + }, + Text = Loc.GetString("cocoon"), + Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/Actions/web.png")), + Priority = 2 + }; + args.Verbs.Add(verb); + } + + private void AddUnCocoonVerb(EntityUid uid, CocoonerComponent component, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract || !HasComp(args.Target)) + return; + + InnateVerb verb = new() + { + Act = () => + { + StartUnCocooning(uid, component, args.Target); + }, + Text = Loc.GetString("uncocoon"), + Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/Actions/web.png")), + Priority = 2 + }; + args.Verbs.Add(verb); + } + + + private void OnDamageChanged(EntityUid uid, CocoonComponent component, DamageChangedEvent args) + { + if (!args.DamageIncreased || args.DamageDelta == null || component.Victim == null) + return; + + var damage = args.DamageDelta * component.DamagePassthrough; + _damageableSystem.TryChangeDamage(component.Victim, damage); + } + + private void StartCocooning(EntityUid uid, CocoonerComponent component, EntityUid target) + { + _popupSystem.PopupEntity(Loc.GetString("cocoon-start-third-person", ("target", Identity.Entity(target, EntityManager)), ("spider", Identity.Entity(uid, EntityManager))), uid, + Shared.Popups.PopupType.MediumCaution); + + var delay = component.CocoonDelay; + + if (HasComp(target)) + delay *= component.CocoonKnockdownMultiplier; + + var args = new DoAfterArgs(EntityManager, uid, delay, new CocoonDoAfterEvent(), uid, target: target) + { + BreakOnMove = true + }; + + _doAfter.TryStartDoAfter(args); + } + + private void StartUnCocooning(EntityUid uid, CocoonerComponent component, EntityUid target) + { + _popupSystem.PopupEntity(Loc.GetString("uncocoon-start-third-person", ("target", target), ("spider", Identity.Entity(uid, EntityManager))), uid, + Shared.Popups.PopupType.MediumCaution); + + var delay = component.CocoonDelay / 2; + + var args = new DoAfterArgs(EntityManager, uid, delay, new UnCocoonDoAfterEvent(), uid, target: target) + { + BreakOnMove = true + }; + + _doAfter.TryStartDoAfter(args); + } + + private void OnCocoonDoAfter(EntityUid uid, CocoonerComponent component, CocoonDoAfterEvent args) + { + if (args.Handled || args.Cancelled || args.Args.Target == null) + return; + + var spawnProto = HasComp(args.Args.Target) ? "CocoonedHumanoid" : "CocoonSmall"; + Transform(args.Args.Target.Value).AttachToGridOrMap(); + var cocoon = Spawn(spawnProto, Transform(args.Args.Target.Value).Coordinates); + + if (!TryComp(cocoon, out var slots)) + return; + + _itemSlots.SetLock(cocoon, BodySlot, false, slots); + _itemSlots.TryInsert(cocoon, BodySlot, args.Args.Target.Value, args.Args.User); + _itemSlots.SetLock(cocoon, BodySlot, true, slots); + + var impact = (spawnProto == "CocoonedHumanoid") ? LogImpact.High : LogImpact.Medium; + + _adminLogger.Add(LogType.Action, impact, $"{ToPrettyString(args.Args.User):player} cocooned {ToPrettyString(args.Args.Target.Value):target}"); + args.Handled = true; + } + + private void OnUnCocoonDoAfter(EntityUid uid, CocoonerComponent component, UnCocoonDoAfterEvent args) + { + if (args.Handled || args.Cancelled || args.Args.Target == null) + return; + + if (TryComp(args.Args.Target.Value, out var butcher)) + { + var spawnEntities = EntitySpawnCollection.GetSpawns(butcher.SpawnedEntities, _robustRandom); + var coords = Transform(args.Args.Target.Value).MapPosition; + EntityUid popupEnt = default!; + foreach (var proto in spawnEntities) + popupEnt = Spawn(proto, coords.Offset(_robustRandom.NextVector2(0.25f))); + } + + _destructibleSystem.DestroyEntity(args.Args.Target.Value); + + _adminLogger.Add(LogType.Action, LogImpact.Low + , $"{ToPrettyString(args.Args.User):player} uncocooned {ToPrettyString(args.Args.Target.Value):target}"); + args.Handled = true; + } + } +} diff --git a/Content.Server/_DV/Vampire/BloodSuckedComponent.cs b/Content.Shared/_DV/Vampire/BloodSuckedComponent.cs similarity index 82% rename from Content.Server/_DV/Vampire/BloodSuckedComponent.cs rename to Content.Shared/_DV/Vampire/BloodSuckedComponent.cs index a86191b434c..aa715a1a0c9 100644 --- a/Content.Server/_DV/Vampire/BloodSuckedComponent.cs +++ b/Content.Shared/_DV/Vampire/BloodSuckedComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Server._DV.Vampire +namespace Content.Shared._DV.Vampire { /// /// For entities who have been sucked. diff --git a/Content.Server/_DV/Vampire/BloodSuckerComponent.cs b/Content.Shared/_DV/Vampire/BloodSuckerComponent.cs similarity index 97% rename from Content.Server/_DV/Vampire/BloodSuckerComponent.cs rename to Content.Shared/_DV/Vampire/BloodSuckerComponent.cs index 80e5d9502f8..31ba03070ac 100644 --- a/Content.Server/_DV/Vampire/BloodSuckerComponent.cs +++ b/Content.Shared/_DV/Vampire/BloodSuckerComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Server._DV.Vampire +namespace Content.Shared._DV.Vampire { [RegisterComponent] public sealed partial class BloodSuckerComponent : Component diff --git a/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs b/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs new file mode 100644 index 00000000000..8e68dbf65bd --- /dev/null +++ b/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs @@ -0,0 +1,199 @@ +using Content.Shared._DV.Cocoon; +using Content.Shared._DV.Vampiric; +using Content.Shared.Administration.Logs; +using Content.Shared.Body.Systems; +using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.Damage; +using Content.Shared.Damage.Prototypes; +using Content.Shared.DoAfter; +using Content.Shared.HealthExaminable; +using Content.Shared.Interaction; +using Content.Shared.Inventory; +using Content.Shared.Popups; +using Content.Shared.Verbs; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Prototypes; +using Robust.Shared.Utility; + +namespace Content.Shared._DV.Vampire +{ + public sealed class BloodSuckerSystem : EntitySystem + { + [Dependency] private readonly SharedBodySystem _bodySystem = default!; + [Dependency] private readonly SharedSolutionContainerSystem _solutionSystem = default!; + [Dependency] private readonly SharedPopupSystem _popups = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly StomachSystem _stomachSystem = default!; + [Dependency] private readonly DamageableSystem _damageableSystem = default!; + [Dependency] private readonly InventorySystem _inventorySystem = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; + [Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent>(AddSuckVerb); + SubscribeLocalEvent(OnHealthExamined); + SubscribeLocalEvent(OnDamageChanged); + SubscribeLocalEvent(OnDoAfter); + } + + private void AddSuckVerb(EntityUid uid, BloodSuckerComponent component, GetVerbsEvent args) + { + + var victim = args.Target; + var ignoreClothes = false; + + if (TryComp(args.Target, out var cocoon)) + { + victim = cocoon.Victim ?? args.Target; + ignoreClothes = cocoon.Victim != null; + } else if (component.WebRequired) + return; + + if (!TryComp(victim, out var bloodstream) || args.User == victim || !args.CanAccess) + return; + + InnateVerb verb = new() + { + Act = () => + { + StartSuckDoAfter(uid, victim, component, bloodstream, !ignoreClothes); // start doafter + }, + Text = Loc.GetString("action-name-suck-blood"), + Icon = new SpriteSpecifier.Texture(new("/Textures/Nyanotrasen/Icons/verbiconfangs.png")), + Priority = 2 + }; + args.Verbs.Add(verb); + } + + private void OnHealthExamined(EntityUid uid, BloodSuckedComponent component, HealthBeingExaminedEvent args) + { + args.Message.PushNewline(); + args.Message.AddMarkup(Loc.GetString("bloodsucked-health-examine", ("target", uid))); + } + + private void OnDamageChanged(EntityUid uid, BloodSuckedComponent component, DamageChangedEvent args) + { + if (args.DamageIncreased) + return; + + if (_prototypeManager.TryIndex("Brute", out var brute) && args.Damageable.Damage.TryGetDamageInGroup(brute, out var bruteTotal) + && _prototypeManager.TryIndex("Airloss", out var airloss) && args.Damageable.Damage.TryGetDamageInGroup(airloss, out var airlossTotal)) + if (bruteTotal == 0 && airlossTotal == 0) + RemComp(uid); + } + + private void OnDoAfter(EntityUid uid, BloodSuckerComponent component, BloodSuckDoAfterEvent args) + { + if (args.Cancelled || args.Handled || args.Args.Target == null) + return; + + args.Handled = TrySuck(uid, args.Args.Target.Value); + } + + public void StartSuckDoAfter(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodSuckerComponent = null, BloodstreamComponent? stream = null, bool doChecks = true) + { + if (!Resolve(bloodsucker, ref bloodSuckerComponent) || !Resolve(victim, ref stream)) + return; + + if (doChecks) + { + if (!_interactionSystem.InRangeUnobstructed(bloodsucker, victim)) + return; + + if (_inventorySystem.TryGetSlotEntity(victim, "head", out var headUid) && HasComp(headUid)) + { + _popups.PopupEntity(Loc.GetString("bloodsucker-fail-helmet", ("helmet", headUid)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + return; + } + + if (_inventorySystem.TryGetSlotEntity(bloodsucker, "mask", out var maskUid) && + EntityManager.TryGetComponent(maskUid, out var blocker) && + blocker.Enabled) + { + _popups.PopupEntity(Loc.GetString("bloodsucker-fail-mask", ("mask", maskUid)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + return; + } + } + + if (stream.BloodReagent != "Blood") + _popups.PopupEntity(Loc.GetString("bloodsucker-not-blood", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + else if (_solutionSystem.PercentFull(victim) != 0) + _popups.PopupEntity(Loc.GetString("bloodsucker-fail-no-blood", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + else + _popups.PopupEntity(Loc.GetString("bloodsucker-doafter-start", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + + _popups.PopupEntity(Loc.GetString("bloodsucker-doafter-start-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); + + var args = new DoAfterArgs(EntityManager, bloodsucker, bloodSuckerComponent.Delay, new BloodSuckDoAfterEvent(), bloodsucker, target: victim) + { + BreakOnMove = false, + DistanceThreshold = 2f, + NeedHand = false + }; + + _doAfter.TryStartDoAfter(args); + } + + public bool TrySuck(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodsuckerComp = null) // begin DetlaV +{ + if (!Resolve(bloodsucker, ref bloodsuckerComp)) return false; + if (!TryValidateVictim(victim)) return false; + + if (!TryGetBloodsuckerStomach(bloodsucker, out var stomach)) return false; + if (!TryValidateSolution(bloodsucker)) return false; + + PlayBloodSuckEffects(bloodsucker, victim); + return CompleteBloodSuck(bloodsucker, victim, stomach, bloodsuckerComp); +} + +private bool TryValidateVictim(EntityUid victim) +{ + if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) return false; + if (_bloodstreamSystem.GetBloodLevelPercentage(victim, bloodstream) == 0.0f) return false; + return true; +} + +private bool TryGetBloodsuckerStomach(EntityUid bloodsucker, out StomachComponent stomach) +{ + stomach = _bodySystem.GetBodyOrganEntityComps(bloodsucker).FirstOrDefault(); + return stomach != null; +} + +private bool TryValidateSolution(EntityUid bloodsucker) +{ + if (_solutionSystem.PercentFull(bloodsucker) >= 1) + { + _popups.PopupEntity(Loc.GetString("drink-component-try-use-drink-had-enough"), bloodsucker, bloodsucker, Shared.Popups.PopupType.MediumCaution); + return false; + } + return true; +} + +private void PlayBloodSuckEffects(EntityUid bloodsucker, EntityUid victim) +{ + _adminLogger.Add(Shared.Database.LogType.MeleeHit, Shared.Database.LogImpact.Medium, $"{ToPrettyString(bloodsucker):player} sucked blood from {ToPrettyString(victim):target}"); + _audio.PlayPvs("/Audio/Items/drink.ogg", bloodsucker); + _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); + _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked", ("target", victim)), bloodsucker, bloodsucker, Shared.Popups.PopupType.Medium); + EnsureComp(victim); +} + +private bool CompleteBloodSuck(EntityUid bloodsucker, EntityUid victim, StomachComponent stomach, BloodSuckerComponent bloodsuckerComp) +{ + if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) return false; + + var extractedBlood = _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSuck); + _stomachSystem.TryTransferSolution(bloodsucker, extractedBlood, stomach); + + DamageSpecifier damage = new(); + damage.DamageDict.Add("Piercing", 1); + _damageableSystem.TryChangeDamage(victim, damage, true, true); + + return true; +} + } +} // End DeltaV diff --git a/Content.Server/_DV/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs b/Content.Shared/_DV/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs similarity index 92% rename from Content.Server/_DV/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs rename to Content.Shared/_DV/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs index 728618a1690..3f473de73b0 100644 --- a/Content.Server/_DV/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs +++ b/Content.Shared/_DV/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Server._DV.Vampire.Injector +namespace Content.Shared._DV.Vampire.Injector { [RegisterComponent] /// diff --git a/Content.Server/_DV/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs b/Content.Shared/_DV/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs similarity index 94% rename from Content.Server/_DV/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs rename to Content.Shared/_DV/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs index 8f1a721093a..4d65ee34a0e 100644 --- a/Content.Server/_DV/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs +++ b/Content.Shared/_DV/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs @@ -1,7 +1,6 @@ -using Content.Server.Popups; using Content.Shared.Interaction; -namespace Content.Server._DV.Vampire.Injector +namespace Content.Shared._DV.Vampire.Injector { public sealed class BloodSuckerGlandInjectorSystem : EntitySystem { From 6a9f767c1b6b40d0d0579d745e4b50bfdca61cca Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Sun, 2 Feb 2025 22:16:48 -0500 Subject: [PATCH 24/26] migrate to shared and small refactor --- .../_DV/Vampire/BloodSuckerSystem.cs | 328 ++++++++++++------ .../BloodSuckDoAfterEvent.cs | 2 +- .../_DV/Vampire/BloodSuckerSystem.cs | 161 +-------- .../BloodSuckerGlandInjectorSystem.cs | 3 +- 4 files changed, 231 insertions(+), 263 deletions(-) rename Content.Shared/_DV/{Vampiric => Vampire}/BloodSuckDoAfterEvent.cs (83%) diff --git a/Content.Server/_DV/Vampire/BloodSuckerSystem.cs b/Content.Server/_DV/Vampire/BloodSuckerSystem.cs index fd8095d0da7..e736c631168 100644 --- a/Content.Server/_DV/Vampire/BloodSuckerSystem.cs +++ b/Content.Server/_DV/Vampire/BloodSuckerSystem.cs @@ -5,20 +5,14 @@ using Content.Server.Nutrition.Components; using Content.Shared._DV.Cocoon; using Content.Shared._DV.Vampire; -using Content.Shared._DV.Vampiric; -using Content.Shared.Administration.Logs; using Content.Shared.Body.Systems; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Damage; -using Content.Shared.Damage.Prototypes; using Content.Shared.DoAfter; -using Content.Shared.HealthExaminable; using Content.Shared.Interaction; using Content.Shared.Inventory; using Content.Shared.Popups; using Content.Shared.Verbs; -using Robust.Shared.Audio.Systems; -using Robust.Shared.Prototypes; using Robust.Shared.Utility; namespace Content.Server._DV.Vampire @@ -29,177 +23,285 @@ public sealed class BloodSuckerSystem : EntitySystem [Dependency] private readonly SharedSolutionContainerSystem _solutionSystem = default!; [Dependency] private readonly SharedPopupSystem _popups = default!; [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly StomachSystem _stomachSystem = default!; [Dependency] private readonly DamageableSystem _damageableSystem = default!; [Dependency] private readonly InventorySystem _inventorySystem = default!; - [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!; - [Dependency] private readonly SharedAudioSystem _audio = default!; + public override void Initialize() { base.Initialize(); SubscribeLocalEvent>(AddSuckVerb); - SubscribeLocalEvent(OnHealthExamined); - SubscribeLocalEvent(OnDamageChanged); SubscribeLocalEvent(OnDoAfter); } private void AddSuckVerb(EntityUid uid, BloodSuckerComponent component, GetVerbsEvent args) { + var (victim, ignoreClothes) = ResolveVictimAndIgnoreClothes(args.Target, component); + if (victim == null || !TryComp(victim.Value, out var bloodstream) || + args.User == victim || !args.CanAccess) + return; - var victim = args.Target; - var ignoreClothes = false; + var verb = CreateSuckVerb(uid, victim.Value, component, bloodstream, ignoreClothes); + args.Verbs.Add(verb); - if (TryComp(args.Target, out var cocoon)) + // Helper method to resolve the victim and ignore clothes flag + (EntityUid? victim, bool ignoreClothes) ResolveVictimAndIgnoreClothes(EntityUid target, + BloodSuckerComponent component) { - victim = cocoon.Victim ?? args.Target; - ignoreClothes = cocoon.Victim != null; - } else if (component.WebRequired) - return; + if (TryComp(target, out var cocoon)) + { + return (cocoon.Victim ?? target, cocoon.Victim != null); + } - if (!TryComp(victim, out var bloodstream) || args.User == victim || !args.CanAccess) - return; + return component.WebRequired ? (null, false) : (target, false); + } - InnateVerb verb = new() + // Local function to encapsulate verb creation + InnateVerb CreateSuckVerb(EntityUid uid, + EntityUid victim, + BloodSuckerComponent component, + BloodstreamComponent bloodstream, + bool ignoreClothes) { - Act = () => + return new InnateVerb { - StartSuckDoAfter(uid, victim, component, bloodstream, !ignoreClothes); // start doafter - }, - Text = Loc.GetString("action-name-suck-blood"), - Icon = new SpriteSpecifier.Texture(new("/Textures/Nyanotrasen/Icons/verbiconfangs.png")), - Priority = 2 - }; - args.Verbs.Add(verb); + Act = () => StartSuckDoAfter(uid, victim, component, bloodstream, !ignoreClothes), + Text = Loc.GetString("action-name-suck-blood"), + Icon = new SpriteSpecifier.Texture(new("/Textures/Nyanotrasen/Icons/verbiconfangs.png")), + Priority = 2 + }; + } } - private void OnHealthExamined(EntityUid uid, BloodSuckedComponent component, HealthBeingExaminedEvent args) - { - args.Message.PushNewline(); - args.Message.AddMarkup(Loc.GetString("bloodsucked-health-examine", ("target", uid))); - } + private const string HeadSlot = "head"; + private const string MaskSlot = "mask"; + private const string BloodName = "Blood"; - private void OnDamageChanged(EntityUid uid, BloodSuckedComponent component, DamageChangedEvent args) + public void StartSuckDoAfter(EntityUid bloodSuckerUid, + EntityUid victimUid, + BloodSuckerComponent? bloodSuckerComp = null, + BloodstreamComponent? bloodstreamComp = null, + bool checkConditions = true) { - if (args.DamageIncreased) + if (!Resolve(bloodSuckerUid, ref bloodSuckerComp) || !Resolve(victimUid, ref bloodstreamComp)) + return; + + if (checkConditions && !PerformPreliminaryChecks(bloodSuckerUid, victimUid)) + return; + + if (!CheckBloodstreamValidity(victimUid, bloodstreamComp)) return; - if (_prototypeManager.TryIndex("Brute", out var brute) && args.Damageable.Damage.TryGetDamageInGroup(brute, out var bruteTotal) - && _prototypeManager.TryIndex("Airloss", out var airloss) && args.Damageable.Damage.TryGetDamageInGroup(airloss, out var airlossTotal)) - if (bruteTotal == 0 && airlossTotal == 0) - RemComp(uid); + NotifySuckStart(bloodSuckerUid, victimUid); + + StartDoAfterProcess(bloodSuckerUid, bloodSuckerComp, victimUid); } - private void OnDoAfter(EntityUid uid, BloodSuckerComponent component, BloodSuckDoAfterEvent args) + private bool PerformPreliminaryChecks(EntityUid bloodSuckerUid, EntityUid victimUid) { - if (args.Cancelled || args.Handled || args.Args.Target == null) - return; + if (!_interactionSystem.InRangeUnobstructed(bloodSuckerUid, victimUid)) + return false; - args.Handled = TrySuck(uid, args.Args.Target.Value); + if (IsWearingHeadProtection(victimUid) || IsWearingIngestionBlockingMask(bloodSuckerUid)) + return false; + + return true; } - public void StartSuckDoAfter(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodSuckerComponent = null, BloodstreamComponent? stream = null, bool doChecks = true) + private bool IsWearingHeadProtection(EntityUid victimUid) { - if (!Resolve(bloodsucker, ref bloodSuckerComponent) || !Resolve(victim, ref stream)) - return; + if (_inventorySystem.TryGetSlotEntity(victimUid, HeadSlot, out var helmetUid) && + HasComp(helmetUid)) + { + _popups.PopupEntity( + Loc.GetString("bloodsucker-fail-helmet", ("helmet", helmetUid)), + victimUid, + victimUid, + Shared.Popups.PopupType.Medium); + return true; + } + + return false; + } - if (doChecks) + private bool IsWearingIngestionBlockingMask(EntityUid bloodSuckerUid) + { + if (_inventorySystem.TryGetSlotEntity(bloodSuckerUid, MaskSlot, out var maskUid) && + EntityManager.TryGetComponent(maskUid, out var blocker) && + blocker.Enabled) { - if (!_interactionSystem.InRangeUnobstructed(bloodsucker, victim)) - return; + _popups.PopupEntity( + Loc.GetString("bloodsucker-fail-mask", ("mask", maskUid)), + bloodSuckerUid, + bloodSuckerUid, + Shared.Popups.PopupType.Medium); + return true; + } - if (_inventorySystem.TryGetSlotEntity(victim, "head", out var headUid) && HasComp(headUid)) - { - _popups.PopupEntity(Loc.GetString("bloodsucker-fail-helmet", ("helmet", headUid)), victim, bloodsucker, Shared.Popups.PopupType.Medium); - return; - } + return false; + } - if (_inventorySystem.TryGetSlotEntity(bloodsucker, "mask", out var maskUid) && - EntityManager.TryGetComponent(maskUid, out var blocker) && - blocker.Enabled) - { - _popups.PopupEntity(Loc.GetString("bloodsucker-fail-mask", ("mask", maskUid)), victim, bloodsucker, Shared.Popups.PopupType.Medium); - return; - } + private bool CheckBloodstreamValidity(EntityUid victimUid, BloodstreamComponent bloodstreamComp) + { + if (bloodstreamComp.BloodReagent != BloodName) + { + _popups.PopupEntity(Loc.GetString("bloodsucker-not-blood", ("target", victimUid)), + victimUid, + victimUid, + Shared.Popups.PopupType.Medium); + return false; } - if (stream.BloodReagent != "Blood") - _popups.PopupEntity(Loc.GetString("bloodsucker-not-blood", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); - else if (_solutionSystem.PercentFull(victim) != 0) - _popups.PopupEntity(Loc.GetString("bloodsucker-fail-no-blood", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); - else - _popups.PopupEntity(Loc.GetString("bloodsucker-doafter-start", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + if (_solutionSystem.PercentFull(victimUid) != 0) + { + _popups.PopupEntity(Loc.GetString("bloodsucker-fail-no-blood", ("target", victimUid)), + victimUid, + victimUid, + Shared.Popups.PopupType.Medium); + return false; + } - _popups.PopupEntity(Loc.GetString("bloodsucker-doafter-start-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); + return true; + } - var args = new DoAfterArgs(EntityManager, bloodsucker, bloodSuckerComponent.Delay, new BloodSuckDoAfterEvent(), bloodsucker, target: victim) + private void NotifySuckStart(EntityUid bloodSuckerUid, EntityUid victimUid) + { + _popups.PopupEntity( + Loc.GetString("bloodsucker-doafter-start", ("target", victimUid)), + victimUid, + bloodSuckerUid, + Shared.Popups.PopupType.Medium); + _popups.PopupEntity( + Loc.GetString("bloodsucker-doafter-start-victim", ("sucker", bloodSuckerUid)), + victimUid, + victimUid, + Shared.Popups.PopupType.LargeCaution); + } + + private void StartDoAfterProcess(EntityUid bloodSuckerUid, + BloodSuckerComponent bloodSuckerComp, + EntityUid victimUid) + { + var doAfterArgs = new DoAfterArgs(EntityManager, + bloodSuckerUid, + bloodSuckerComp.Delay, + new BloodSuckDoAfterEvent(), + bloodSuckerUid, + victimUid) { BreakOnMove = false, DistanceThreshold = 2f, NeedHand = false }; + _doAfter.TryStartDoAfter(doAfterArgs); + } - _doAfter.TryStartDoAfter(args); + private StomachComponent? TryGetStomachComponentFromBloodsucker(EntityUid bloodsucker) + { + var stomachComponent = _bodySystem.GetBodyOrganEntityComps(bloodsucker).FirstOrDefault(); + return stomachComponent; } - public bool TrySuck(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodsuckerComp = null) // begin DetlaV -{ - if (!Resolve(bloodsucker, ref bloodsuckerComp)) return false; - if (!TryValidateVictim(victim)) return false; + private const float MinBloodLevelPercentage = 0.0f; - if (!TryGetBloodsuckerStomach(bloodsucker, out var stomach)) return false; - if (!TryValidateSolution(bloodsucker)) return false; + private bool TryValidateVictim(EntityUid victim) + { + if (!TryGetValidBloodstream(victim, out var bloodstream)) + return false; - PlayBloodSuckEffects(bloodsucker, victim); - return CompleteBloodSuck(bloodsucker, victim, stomach, bloodsuckerComp); -} + return IsBloodLevelAboveMinimum(victim, bloodstream); + } -private bool TryValidateVictim(EntityUid victim) + private bool TryGetValidBloodstream(EntityUid victim, out BloodstreamComponent bloodstream) { - if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) return false; - if (_bloodstreamSystem.GetBloodLevelPercentage(victim, bloodstream) == 0.0f) return false; - return true; -} + bloodstream = null!; -private bool TryGetBloodsuckerStomach(EntityUid bloodsucker, out StomachComponent stomach) -{ - stomach = _bodySystem.GetBodyOrganEntityComps(bloodsucker).FirstOrDefault(); - return stomach != null; -} + // Ensure the victim is valid + if (victim == EntityUid.Invalid) + { + Logger.Warning("Attempted to get a BloodstreamComponent from an invalid EntityUid."); + return false; + } -private bool TryValidateSolution(EntityUid bloodsucker) -{ - if (_solutionSystem.PercentFull(bloodsucker) >= 1) + // Check if blood solution exists + if (bloodstream.BloodSolution == null) { - _popups.PopupEntity(Loc.GetString("drink-component-try-use-drink-had-enough"), bloodsucker, bloodsucker, Shared.Popups.PopupType.MediumCaution); + Logger.Warning($"BloodstreamComponent on {victim} does not have a valid BloodSolution."); return false; } + + // Passed all checks return true; } -private void PlayBloodSuckEffects(EntityUid bloodsucker, EntityUid victim) -{ - _adminLogger.Add(Shared.Database.LogType.MeleeHit, Shared.Database.LogImpact.Medium, $"{ToPrettyString(bloodsucker):player} sucked blood from {ToPrettyString(victim):target}"); - _audio.PlayPvs("/Audio/Items/drink.ogg", bloodsucker); - _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); - _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked", ("target", victim)), bloodsucker, bloodsucker, Shared.Popups.PopupType.Medium); - EnsureComp(victim); -} + private bool IsBloodLevelAboveMinimum(EntityUid victim, BloodstreamComponent bloodstream) + { + return _bloodstreamSystem.GetBloodLevelPercentage(victim, bloodstream) > MinBloodLevelPercentage; + } -private bool CompleteBloodSuck(EntityUid bloodsucker, EntityUid victim, StomachComponent stomach, BloodSuckerComponent bloodsuckerComp) -{ - if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) return false; + private void OnDoAfter(EntityUid uid, BloodSuckerComponent component, BloodSuckDoAfterEvent args) + { + if (IsDoAfterInvalid(args)) + return; + + if (args.Args.Target is EntityUid target) + { + args.Handled = TrySuck(uid, target); + } } - var extractedBlood = _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSuck); - _stomachSystem.TryTransferSolution(bloodsucker, extractedBlood, stomach); + private static bool IsDoAfterInvalid(BloodSuckDoAfterEvent args) + { + return args.Cancelled || args.Handled || args.Args.Target == null; + } - DamageSpecifier damage = new(); - damage.DamageDict.Add("Piercing", 1); - _damageableSystem.TryChangeDamage(victim, damage, true, true); - return true; -} + public bool TrySuck(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodsuckerComp = null) + { + var sharedSystem = EntityManager.EntitySysManager.GetEntitySystem(); + + if (!AreValidInputs(bloodsucker, victim, sharedSystem, ref bloodsuckerComp, out var bloodsuckerStomach)) + return false; + + sharedSystem.PlayBloodSuckEffects(bloodsucker, victim); + + return CompleteBloodSuck(bloodsucker, victim, bloodsuckerStomach, bloodsuckerComp); + } + + private bool AreValidInputs(EntityUid bloodsucker, + EntityUid victim, + SharedBloodSuckerSystem sharedSystem, + ref BloodSuckerComponent? bloodsuckerComp, + out StomachComponent bloodsuckerStomach) + { + bloodsuckerStomach = default; + + return Resolve(bloodsucker, ref bloodsuckerComp) && + TryValidateVictim(victim) && + StomachComponent(bloodsucker, out bloodsuckerStomach) && + sharedSystem.TryValidateSolution(bloodsucker); + } + private bool CompleteBloodSuck(EntityUid bloodsucker, + EntityUid victim, + StomachComponent stomach, + BloodSuckerComponent bloodsuckerComp) + { + if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) + return false; + + var extractedBloodSolution = + _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSuck); + _stomachSystem.TryTransferSolution(bloodsucker, extractedBloodSolution, stomach); + + ApplyPiercingDamage(victim, 5); + return true; + } + + private void ApplyPiercingDamage(EntityUid victim, int damageAmount) + { + var damage = new DamageSpecifier { DamageDict = { { "Piercing", damageAmount } } }; + _damageableSystem.TryChangeDamage(victim, damage, true, true); + } } -} // End DeltaV +} diff --git a/Content.Shared/_DV/Vampiric/BloodSuckDoAfterEvent.cs b/Content.Shared/_DV/Vampire/BloodSuckDoAfterEvent.cs similarity index 83% rename from Content.Shared/_DV/Vampiric/BloodSuckDoAfterEvent.cs rename to Content.Shared/_DV/Vampire/BloodSuckDoAfterEvent.cs index bc780a96298..109769f21f5 100644 --- a/Content.Shared/_DV/Vampiric/BloodSuckDoAfterEvent.cs +++ b/Content.Shared/_DV/Vampire/BloodSuckDoAfterEvent.cs @@ -1,7 +1,7 @@ using Content.Shared.DoAfter; using Robust.Shared.Serialization; -namespace Content.Shared._DV.Vampiric +namespace Content.Shared._DV.Vampire { [Serializable, NetSerializable] public sealed partial class BloodSuckDoAfterEvent : SimpleDoAfterEvent diff --git a/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs b/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs index 8e68dbf65bd..9f6cafa2adf 100644 --- a/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs +++ b/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs @@ -1,73 +1,28 @@ -using Content.Shared._DV.Cocoon; -using Content.Shared._DV.Vampiric; using Content.Shared.Administration.Logs; -using Content.Shared.Body.Systems; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Damage; using Content.Shared.Damage.Prototypes; -using Content.Shared.DoAfter; using Content.Shared.HealthExaminable; -using Content.Shared.Interaction; -using Content.Shared.Inventory; using Content.Shared.Popups; -using Content.Shared.Verbs; using Robust.Shared.Audio.Systems; using Robust.Shared.Prototypes; -using Robust.Shared.Utility; namespace Content.Shared._DV.Vampire { public sealed class BloodSuckerSystem : EntitySystem { - [Dependency] private readonly SharedBodySystem _bodySystem = default!; [Dependency] private readonly SharedSolutionContainerSystem _solutionSystem = default!; [Dependency] private readonly SharedPopupSystem _popups = default!; - [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly StomachSystem _stomachSystem = default!; - [Dependency] private readonly DamageableSystem _damageableSystem = default!; - [Dependency] private readonly InventorySystem _inventorySystem = default!; [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; - [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; - [Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; public override void Initialize() { base.Initialize(); - SubscribeLocalEvent>(AddSuckVerb); SubscribeLocalEvent(OnHealthExamined); SubscribeLocalEvent(OnDamageChanged); - SubscribeLocalEvent(OnDoAfter); } - private void AddSuckVerb(EntityUid uid, BloodSuckerComponent component, GetVerbsEvent args) - { - - var victim = args.Target; - var ignoreClothes = false; - - if (TryComp(args.Target, out var cocoon)) - { - victim = cocoon.Victim ?? args.Target; - ignoreClothes = cocoon.Victim != null; - } else if (component.WebRequired) - return; - - if (!TryComp(victim, out var bloodstream) || args.User == victim || !args.CanAccess) - return; - - InnateVerb verb = new() - { - Act = () => - { - StartSuckDoAfter(uid, victim, component, bloodstream, !ignoreClothes); // start doafter - }, - Text = Loc.GetString("action-name-suck-blood"), - Icon = new SpriteSpecifier.Texture(new("/Textures/Nyanotrasen/Icons/verbiconfangs.png")), - Priority = 2 - }; - args.Verbs.Add(verb); - } private void OnHealthExamined(EntityUid uid, BloodSuckedComponent component, HealthBeingExaminedEvent args) { @@ -86,114 +41,24 @@ private void OnDamageChanged(EntityUid uid, BloodSuckedComponent component, Dama RemComp(uid); } - private void OnDoAfter(EntityUid uid, BloodSuckerComponent component, BloodSuckDoAfterEvent args) - { - if (args.Cancelled || args.Handled || args.Args.Target == null) - return; - - args.Handled = TrySuck(uid, args.Args.Target.Value); - } - public void StartSuckDoAfter(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodSuckerComponent = null, BloodstreamComponent? stream = null, bool doChecks = true) + private bool TryValidateSolution(EntityUid bloodsucker) { - if (!Resolve(bloodsucker, ref bloodSuckerComponent) || !Resolve(victim, ref stream)) - return; - - if (doChecks) + if (_solutionSystem.PercentFull(bloodsucker) >= 1) { - if (!_interactionSystem.InRangeUnobstructed(bloodsucker, victim)) - return; - - if (_inventorySystem.TryGetSlotEntity(victim, "head", out var headUid) && HasComp(headUid)) - { - _popups.PopupEntity(Loc.GetString("bloodsucker-fail-helmet", ("helmet", headUid)), victim, bloodsucker, Shared.Popups.PopupType.Medium); - return; - } - - if (_inventorySystem.TryGetSlotEntity(bloodsucker, "mask", out var maskUid) && - EntityManager.TryGetComponent(maskUid, out var blocker) && - blocker.Enabled) - { - _popups.PopupEntity(Loc.GetString("bloodsucker-fail-mask", ("mask", maskUid)), victim, bloodsucker, Shared.Popups.PopupType.Medium); - return; - } + _popups.PopupEntity(Loc.GetString("drink-component-try-use-drink-had-enough"), bloodsucker, bloodsucker, Shared.Popups.PopupType.MediumCaution); + return false; } - - if (stream.BloodReagent != "Blood") - _popups.PopupEntity(Loc.GetString("bloodsucker-not-blood", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); - else if (_solutionSystem.PercentFull(victim) != 0) - _popups.PopupEntity(Loc.GetString("bloodsucker-fail-no-blood", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); - else - _popups.PopupEntity(Loc.GetString("bloodsucker-doafter-start", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); - - _popups.PopupEntity(Loc.GetString("bloodsucker-doafter-start-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); - - var args = new DoAfterArgs(EntityManager, bloodsucker, bloodSuckerComponent.Delay, new BloodSuckDoAfterEvent(), bloodsucker, target: victim) - { - BreakOnMove = false, - DistanceThreshold = 2f, - NeedHand = false - }; - - _doAfter.TryStartDoAfter(args); + return true; } - public bool TrySuck(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodsuckerComp = null) // begin DetlaV -{ - if (!Resolve(bloodsucker, ref bloodsuckerComp)) return false; - if (!TryValidateVictim(victim)) return false; - - if (!TryGetBloodsuckerStomach(bloodsucker, out var stomach)) return false; - if (!TryValidateSolution(bloodsucker)) return false; - - PlayBloodSuckEffects(bloodsucker, victim); - return CompleteBloodSuck(bloodsucker, victim, stomach, bloodsuckerComp); -} - -private bool TryValidateVictim(EntityUid victim) -{ - if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) return false; - if (_bloodstreamSystem.GetBloodLevelPercentage(victim, bloodstream) == 0.0f) return false; - return true; -} - -private bool TryGetBloodsuckerStomach(EntityUid bloodsucker, out StomachComponent stomach) -{ - stomach = _bodySystem.GetBodyOrganEntityComps(bloodsucker).FirstOrDefault(); - return stomach != null; -} - -private bool TryValidateSolution(EntityUid bloodsucker) -{ - if (_solutionSystem.PercentFull(bloodsucker) >= 1) - { - _popups.PopupEntity(Loc.GetString("drink-component-try-use-drink-had-enough"), bloodsucker, bloodsucker, Shared.Popups.PopupType.MediumCaution); - return false; + public void PlayBloodSuckEffects(EntityUid bloodsucker, EntityUid victim) + { + _adminLogger.Add(Shared.Database.LogType.MeleeHit, Shared.Database.LogImpact.Medium, $"{ToPrettyString(bloodsucker):player} sucked blood from {ToPrettyString(victim):target}"); + _audio.PlayPvs("/Audio/Items/drink.ogg", bloodsucker); + _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); + _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked", ("target", victim)), bloodsucker, bloodsucker, Shared.Popups.PopupType.Medium); + EnsureComp(victim); + } } - return true; -} - -private void PlayBloodSuckEffects(EntityUid bloodsucker, EntityUid victim) -{ - _adminLogger.Add(Shared.Database.LogType.MeleeHit, Shared.Database.LogImpact.Medium, $"{ToPrettyString(bloodsucker):player} sucked blood from {ToPrettyString(victim):target}"); - _audio.PlayPvs("/Audio/Items/drink.ogg", bloodsucker); - _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); - _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked", ("target", victim)), bloodsucker, bloodsucker, Shared.Popups.PopupType.Medium); - EnsureComp(victim); -} - -private bool CompleteBloodSuck(EntityUid bloodsucker, EntityUid victim, StomachComponent stomach, BloodSuckerComponent bloodsuckerComp) -{ - if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) return false; - - var extractedBlood = _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSuck); - _stomachSystem.TryTransferSolution(bloodsucker, extractedBlood, stomach); - - DamageSpecifier damage = new(); - damage.DamageDict.Add("Piercing", 1); - _damageableSystem.TryChangeDamage(victim, damage, true, true); - - return true; } - } -} // End DeltaV diff --git a/Content.Shared/_DV/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs b/Content.Shared/_DV/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs index 4d65ee34a0e..fb20c004f94 100644 --- a/Content.Shared/_DV/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs +++ b/Content.Shared/_DV/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs @@ -1,10 +1,11 @@ using Content.Shared.Interaction; +using Content.Shared.Popups; namespace Content.Shared._DV.Vampire.Injector { public sealed class BloodSuckerGlandInjectorSystem : EntitySystem { - [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; public override void Initialize() { base.Initialize(); From e7faa929e5716a8aecae36cdbc2089277d50667b Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Tue, 4 Feb 2025 12:40:59 -0500 Subject: [PATCH 25/26] i have no idea B) --- .../_DV/Vampire/BloodSuckerSystem.cs | 318 +++++------------- .../_DV/Vampire/BloodSuckDoAfterEvent.cs | 8 +- .../_DV/Vampire/BloodSuckerComponent.cs | 6 +- .../_DV/Vampire/BloodSuckerSystem.cs | 39 ++- .../BloodSuckerGlandInjectorComponent.cs | 2 +- 5 files changed, 119 insertions(+), 254 deletions(-) diff --git a/Content.Server/_DV/Vampire/BloodSuckerSystem.cs b/Content.Server/_DV/Vampire/BloodSuckerSystem.cs index e736c631168..d66e07c28d7 100644 --- a/Content.Server/_DV/Vampire/BloodSuckerSystem.cs +++ b/Content.Server/_DV/Vampire/BloodSuckerSystem.cs @@ -1,34 +1,34 @@ using System.Linq; -using Content.Server.Atmos.Components; -using Content.Server.Body.Components; -using Content.Server.Body.Systems; -using Content.Server.Nutrition.Components; -using Content.Shared._DV.Cocoon; -using Content.Shared._DV.Vampire; -using Content.Shared.Body.Systems; -using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.Verbs; using Content.Shared.Damage; using Content.Shared.DoAfter; using Content.Shared.Interaction; using Content.Shared.Inventory; -using Content.Shared.Popups; -using Content.Shared.Verbs; +using Content.Shared._DV.Vampire; +using Content.Shared._DV.Cocoon; +using Content.Server.Atmos.Components; +using Content.Server.Body.Components; +using Content.Server.Body.Systems; +using Content.Shared.Chemistry.EntitySystems; +using Content.Server.Popups; +using Content.Server.DoAfter; +using Content.Server.Nutrition.Components; +using Content.Shared.Vampire; using Robust.Shared.Utility; -namespace Content.Server._DV.Vampire +namespace Content.Server.Vampire { public sealed class BloodSuckerSystem : EntitySystem { - [Dependency] private readonly SharedBodySystem _bodySystem = default!; + [Dependency] private readonly BodySystem _bodySystem = default!; [Dependency] private readonly SharedSolutionContainerSystem _solutionSystem = default!; - [Dependency] private readonly SharedPopupSystem _popups = default!; - [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; + [Dependency] private readonly PopupSystem _popups = default!; + [Dependency] private readonly DoAfterSystem _doAfter = default!; [Dependency] private readonly StomachSystem _stomachSystem = default!; [Dependency] private readonly DamageableSystem _damageableSystem = default!; [Dependency] private readonly InventorySystem _inventorySystem = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!; - public override void Initialize() { base.Initialize(); @@ -38,270 +38,134 @@ public override void Initialize() private void AddSuckVerb(EntityUid uid, BloodSuckerComponent component, GetVerbsEvent args) { - var (victim, ignoreClothes) = ResolveVictimAndIgnoreClothes(args.Target, component); - if (victim == null || !TryComp(victim.Value, out var bloodstream) || - args.User == victim || !args.CanAccess) - return; - var verb = CreateSuckVerb(uid, victim.Value, component, bloodstream, ignoreClothes); - args.Verbs.Add(verb); + var victim = args.Target; + var ignoreClothes = false; - // Helper method to resolve the victim and ignore clothes flag - (EntityUid? victim, bool ignoreClothes) ResolveVictimAndIgnoreClothes(EntityUid target, - BloodSuckerComponent component) + if (TryComp(args.Target, out var cocoon)) { - if (TryComp(target, out var cocoon)) - { - return (cocoon.Victim ?? target, cocoon.Victim != null); - } - - return component.WebRequired ? (null, false) : (target, false); + victim = cocoon.Victim ?? args.Target; + ignoreClothes = cocoon.Victim != null; } + else if (component.WebRequired) + return; + + if (!TryComp(victim, out var bloodstream) || args.User == victim || !args.CanAccess) + return; - // Local function to encapsulate verb creation - InnateVerb CreateSuckVerb(EntityUid uid, - EntityUid victim, - BloodSuckerComponent component, - BloodstreamComponent bloodstream, - bool ignoreClothes) + InnateVerb verb = new() { - return new InnateVerb + Act = () => { - Act = () => StartSuckDoAfter(uid, victim, component, bloodstream, !ignoreClothes), - Text = Loc.GetString("action-name-suck-blood"), - Icon = new SpriteSpecifier.Texture(new("/Textures/Nyanotrasen/Icons/verbiconfangs.png")), - Priority = 2 - }; - } + StartSuckDoAfter(uid, victim, component, bloodstream, !ignoreClothes); // start doafter + }, + Text = Loc.GetString("action-name-suck-blood"), + Icon = new SpriteSpecifier.Texture(new("/Textures/Nyanotrasen/Icons/verbiconfangs.png")), + Priority = 2, + }; + args.Verbs.Add(verb); } - private const string HeadSlot = "head"; - private const string MaskSlot = "mask"; - private const string BloodName = "Blood"; - public void StartSuckDoAfter(EntityUid bloodSuckerUid, - EntityUid victimUid, - BloodSuckerComponent? bloodSuckerComp = null, - BloodstreamComponent? bloodstreamComp = null, - bool checkConditions = true) + private void OnDoAfter(EntityUid uid, BloodSuckerComponent component, BloodSuckDoAfterEvent args) { - if (!Resolve(bloodSuckerUid, ref bloodSuckerComp) || !Resolve(victimUid, ref bloodstreamComp)) - return; - - if (checkConditions && !PerformPreliminaryChecks(bloodSuckerUid, victimUid)) + if (args.Cancelled || args.Handled || args.Args.Target == null) return; - if (!CheckBloodstreamValidity(victimUid, bloodstreamComp)) - return; - - NotifySuckStart(bloodSuckerUid, victimUid); - - StartDoAfterProcess(bloodSuckerUid, bloodSuckerComp, victimUid); + args.Handled = TrySuck(uid, args.Args.Target.Value); } - private bool PerformPreliminaryChecks(EntityUid bloodSuckerUid, EntityUid victimUid) + public void StartSuckDoAfter(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodSuckerComponent = null, BloodstreamComponent? stream = null, bool doChecks = true) { - if (!_interactionSystem.InRangeUnobstructed(bloodSuckerUid, victimUid)) - return false; - - if (IsWearingHeadProtection(victimUid) || IsWearingIngestionBlockingMask(bloodSuckerUid)) - return false; - - return true; - } - - private bool IsWearingHeadProtection(EntityUid victimUid) - { - if (_inventorySystem.TryGetSlotEntity(victimUid, HeadSlot, out var helmetUid) && - HasComp(helmetUid)) - { - _popups.PopupEntity( - Loc.GetString("bloodsucker-fail-helmet", ("helmet", helmetUid)), - victimUid, - victimUid, - Shared.Popups.PopupType.Medium); - return true; - } - - return false; - } + if (!Resolve(bloodsucker, ref bloodSuckerComponent) || !Resolve(victim, ref stream)) + return; - private bool IsWearingIngestionBlockingMask(EntityUid bloodSuckerUid) - { - if (_inventorySystem.TryGetSlotEntity(bloodSuckerUid, MaskSlot, out var maskUid) && - EntityManager.TryGetComponent(maskUid, out var blocker) && - blocker.Enabled) + if (doChecks) { - _popups.PopupEntity( - Loc.GetString("bloodsucker-fail-mask", ("mask", maskUid)), - bloodSuckerUid, - bloodSuckerUid, - Shared.Popups.PopupType.Medium); - return true; - } - - return false; - } + if (!_interactionSystem.InRangeUnobstructed(bloodsucker, victim)) + return; - private bool CheckBloodstreamValidity(EntityUid victimUid, BloodstreamComponent bloodstreamComp) - { - if (bloodstreamComp.BloodReagent != BloodName) - { - _popups.PopupEntity(Loc.GetString("bloodsucker-not-blood", ("target", victimUid)), - victimUid, - victimUid, - Shared.Popups.PopupType.Medium); - return false; - } + if (_inventorySystem.TryGetSlotEntity(victim, "head", out var headUid) && HasComp(headUid)) + { + _popups.PopupEntity(Loc.GetString("bloodsucker-fail-helmet", ("helmet", headUid)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + return; + } - if (_solutionSystem.PercentFull(victimUid) != 0) - { - _popups.PopupEntity(Loc.GetString("bloodsucker-fail-no-blood", ("target", victimUid)), - victimUid, - victimUid, - Shared.Popups.PopupType.Medium); - return false; + if (_inventorySystem.TryGetSlotEntity(bloodsucker, "mask", out var maskUid) && + EntityManager.TryGetComponent(maskUid, out var blocker) && + blocker.Enabled) + { + _popups.PopupEntity(Loc.GetString("bloodsucker-fail-mask", ("mask", maskUid)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + return; + } } - return true; - } + if (stream.BloodReagent != "Blood") + _popups.PopupEntity(Loc.GetString("bloodsucker-not-blood", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + else if (_solutionSystem.PercentFull(victim) != 0) + _popups.PopupEntity(Loc.GetString("bloodsucker-fail-no-blood", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + else + _popups.PopupEntity(Loc.GetString("bloodsucker-doafter-start", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); - private void NotifySuckStart(EntityUid bloodSuckerUid, EntityUid victimUid) - { - _popups.PopupEntity( - Loc.GetString("bloodsucker-doafter-start", ("target", victimUid)), - victimUid, - bloodSuckerUid, - Shared.Popups.PopupType.Medium); - _popups.PopupEntity( - Loc.GetString("bloodsucker-doafter-start-victim", ("sucker", bloodSuckerUid)), - victimUid, - victimUid, - Shared.Popups.PopupType.LargeCaution); - } + _popups.PopupEntity(Loc.GetString("bloodsucker-doafter-start-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); - private void StartDoAfterProcess(EntityUid bloodSuckerUid, - BloodSuckerComponent bloodSuckerComp, - EntityUid victimUid) - { - var doAfterArgs = new DoAfterArgs(EntityManager, - bloodSuckerUid, - bloodSuckerComp.Delay, - new BloodSuckDoAfterEvent(), - bloodSuckerUid, - victimUid) + var args = new DoAfterArgs(EntityManager, bloodsucker, bloodSuckerComponent.Delay, new BloodSuckDoAfterEvent(), bloodsucker, target: victim) { BreakOnMove = false, DistanceThreshold = 2f, NeedHand = false }; - _doAfter.TryStartDoAfter(doAfterArgs); - } - private StomachComponent? TryGetStomachComponentFromBloodsucker(EntityUid bloodsucker) - { - var stomachComponent = _bodySystem.GetBodyOrganEntityComps(bloodsucker).FirstOrDefault(); - return stomachComponent; + _doAfter.TryStartDoAfter(args); } - private const float MinBloodLevelPercentage = 0.0f; + public bool TrySuck(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodsuckerComp = null) - private bool TryValidateVictim(EntityUid victim) - { - if (!TryGetValidBloodstream(victim, out var bloodstream)) - return false; - - return IsBloodLevelAboveMinimum(victim, bloodstream); - } - - private bool TryGetValidBloodstream(EntityUid victim, out BloodstreamComponent bloodstream) -{ - bloodstream = null!; - - // Ensure the victim is valid - if (victim == EntityUid.Invalid) - { - Logger.Warning("Attempted to get a BloodstreamComponent from an invalid EntityUid."); - return false; - } - - // Check if blood solution exists - if (bloodstream.BloodSolution == null) - { - Logger.Warning($"BloodstreamComponent on {victim} does not have a valid BloodSolution."); - return false; - } - // Passed all checks - return true; -} - - private bool IsBloodLevelAboveMinimum(EntityUid victim, BloodstreamComponent bloodstream) { - return _bloodstreamSystem.GetBloodLevelPercentage(victim, bloodstream) > MinBloodLevelPercentage; - } + var sharedBloodSuckerSystem = EntitySystem.Get(); - private void OnDoAfter(EntityUid uid, BloodSuckerComponent component, BloodSuckDoAfterEvent args) - { - if (IsDoAfterInvalid(args)) - return; + if (!Resolve(bloodsucker, ref bloodsuckerComp)) + return false; + if (!TryValidateVictim(victim)) + return false; - if (args.Args.Target is EntityUid target) - { - args.Handled = TrySuck(uid, target); - } } + if (!TryGetBloodsuckerStomach(bloodsucker, out var stomach)) + return false; + if (!sharedBloodSuckerSystem.TryValidateSolution(bloodsucker)) + return false; - private static bool IsDoAfterInvalid(BloodSuckDoAfterEvent args) - { - return args.Cancelled || args.Handled || args.Args.Target == null; + sharedBloodSuckerSystem.PlayBloodSuckEffects(bloodsucker, victim); + return CompleteBloodSuck(bloodsucker, victim, stomach, bloodsuckerComp); } - - public bool TrySuck(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodsuckerComp = null) + private bool TryValidateVictim(EntityUid victim) { - var sharedSystem = EntityManager.EntitySysManager.GetEntitySystem(); - - if (!AreValidInputs(bloodsucker, victim, sharedSystem, ref bloodsuckerComp, out var bloodsuckerStomach)) + if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) return false; - - sharedSystem.PlayBloodSuckEffects(bloodsucker, victim); - - return CompleteBloodSuck(bloodsucker, victim, bloodsuckerStomach, bloodsuckerComp); + return _bloodstreamSystem.GetBloodLevelPercentage(victim, bloodstream) != 0.0f; } - private bool AreValidInputs(EntityUid bloodsucker, - EntityUid victim, - SharedBloodSuckerSystem sharedSystem, - ref BloodSuckerComponent? bloodsuckerComp, - out StomachComponent bloodsuckerStomach) + private bool TryGetBloodsuckerStomach(EntityUid bloodsucker, out StomachComponent stomach) { - bloodsuckerStomach = default; - - return Resolve(bloodsucker, ref bloodsuckerComp) && - TryValidateVictim(victim) && - StomachComponent(bloodsucker, out bloodsuckerStomach) && - sharedSystem.TryValidateSolution(bloodsucker); + stomach = _bodySystem.GetBodyOrganEntityComps(bloodsucker).FirstOrDefault(); + return true; } - private bool CompleteBloodSuck(EntityUid bloodsucker, - EntityUid victim, - StomachComponent stomach, - BloodSuckerComponent bloodsuckerComp) + + + private bool CompleteBloodSuck(EntityUid bloodsucker, EntityUid victim, StomachComponent stomach, BloodSuckerComponent bloodsuckerComp) { if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) return false; - var extractedBloodSolution = - _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSuck); - _stomachSystem.TryTransferSolution(bloodsucker, extractedBloodSolution, stomach); + var extractedBlood = _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSuck); + _stomachSystem.TryTransferSolution(bloodsucker, extractedBlood, stomach); - ApplyPiercingDamage(victim, 5); - return true; - } + DamageSpecifier damage = new(); + damage.DamageDict.Add("Piercing", 1); + _damageableSystem.TryChangeDamage(victim, damage, true); - private void ApplyPiercingDamage(EntityUid victim, int damageAmount) - { - var damage = new DamageSpecifier { DamageDict = { { "Piercing", damageAmount } } }; - _damageableSystem.TryChangeDamage(victim, damage, true, true); + return true; } } } diff --git a/Content.Shared/_DV/Vampire/BloodSuckDoAfterEvent.cs b/Content.Shared/_DV/Vampire/BloodSuckDoAfterEvent.cs index 109769f21f5..5b88d2ddc99 100644 --- a/Content.Shared/_DV/Vampire/BloodSuckDoAfterEvent.cs +++ b/Content.Shared/_DV/Vampire/BloodSuckDoAfterEvent.cs @@ -1,10 +1,8 @@ -using Content.Shared.DoAfter; -using Robust.Shared.Serialization; - namespace Content.Shared._DV.Vampire { - [Serializable, NetSerializable] - public sealed partial class BloodSuckDoAfterEvent : SimpleDoAfterEvent + [DataDefinition] + public partial class BloodSuckDoAfterEvent { } } + diff --git a/Content.Shared/_DV/Vampire/BloodSuckerComponent.cs b/Content.Shared/_DV/Vampire/BloodSuckerComponent.cs index 31ba03070ac..d2a28318989 100644 --- a/Content.Shared/_DV/Vampire/BloodSuckerComponent.cs +++ b/Content.Shared/_DV/Vampire/BloodSuckerComponent.cs @@ -1,7 +1,7 @@ namespace Content.Shared._DV.Vampire { [RegisterComponent] - public sealed partial class BloodSuckerComponent : Component + public partial class BloodSuckerComponent { /// /// How much to suck each time we suck. @@ -21,7 +21,7 @@ public sealed partial class BloodSuckerComponent : Component /// Whether to inject chems into a chemstream when we suck something. /// [DataField("injectWhenSuck")] - public bool InjectWhenSuck = false; + public bool InjectWhenSuck; /// /// How many units of our injected chem to inject. @@ -39,6 +39,6 @@ public sealed partial class BloodSuckerComponent : Component /// Whether we need to web the thing up first... /// [DataField("webRequired")] - public bool WebRequired = false; + public bool WebRequired; } } diff --git a/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs b/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs index 9f6cafa2adf..8e32db925d1 100644 --- a/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs +++ b/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs @@ -1,15 +1,17 @@ +using Content.Shared._DV.Vampire; using Content.Shared.Administration.Logs; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Damage; using Content.Shared.Damage.Prototypes; +using Content.Shared.Database; using Content.Shared.HealthExaminable; using Content.Shared.Popups; using Robust.Shared.Audio.Systems; using Robust.Shared.Prototypes; -namespace Content.Shared._DV.Vampire +namespace Content.Shared.Vampire { - public sealed class BloodSuckerSystem : EntitySystem + public sealed class SharedBloodSuckerSystem : EntitySystem { [Dependency] private readonly SharedSolutionContainerSystem _solutionSystem = default!; [Dependency] private readonly SharedPopupSystem _popups = default!; @@ -27,7 +29,7 @@ public override void Initialize() private void OnHealthExamined(EntityUid uid, BloodSuckedComponent component, HealthBeingExaminedEvent args) { args.Message.PushNewline(); - args.Message.AddMarkup(Loc.GetString("bloodsucked-health-examine", ("target", uid))); + args.Message.AddMarkupOrThrow(Loc.GetString("bloodsucked-health-examine", ("target", uid))); } private void OnDamageChanged(EntityUid uid, BloodSuckedComponent component, DamageChangedEvent args) @@ -35,30 +37,31 @@ private void OnDamageChanged(EntityUid uid, BloodSuckedComponent component, Dama if (args.DamageIncreased) return; - if (_prototypeManager.TryIndex("Brute", out var brute) && args.Damageable.Damage.TryGetDamageInGroup(brute, out var bruteTotal) - && _prototypeManager.TryIndex("Airloss", out var airloss) && args.Damageable.Damage.TryGetDamageInGroup(airloss, out var airlossTotal)) - if (bruteTotal == 0 && airlossTotal == 0) - RemComp(uid); + if (!_prototypeManager.TryIndex("Brute", out var brute) || + !args.Damageable.Damage.TryGetDamageInGroup(brute, out var bruteTotal) + || !_prototypeManager.TryIndex("Airloss", out var airloss) || + !args.Damageable.Damage.TryGetDamageInGroup(airloss, out var airlossTotal)) + return; + if (bruteTotal == 0 && airlossTotal == 0) + RemComp(uid); } - - private bool TryValidateSolution(EntityUid bloodsucker) + public bool TryValidateSolution(EntityUid bloodsucker) { - if (_solutionSystem.PercentFull(bloodsucker) >= 1) - { - _popups.PopupEntity(Loc.GetString("drink-component-try-use-drink-had-enough"), bloodsucker, bloodsucker, Shared.Popups.PopupType.MediumCaution); - return false; - } - return true; + if (!(_solutionSystem.PercentFull(bloodsucker) >= 1)) + return true; + _popups.PopupEntity(Loc.GetString("drink-component-try-use-drink-had-enough"), bloodsucker, bloodsucker, PopupType.MediumCaution); + return false; } public void PlayBloodSuckEffects(EntityUid bloodsucker, EntityUid victim) { - _adminLogger.Add(Shared.Database.LogType.MeleeHit, Shared.Database.LogImpact.Medium, $"{ToPrettyString(bloodsucker):player} sucked blood from {ToPrettyString(victim):target}"); + _adminLogger.Add(LogType.MeleeHit, LogImpact.Medium, $"{ToPrettyString(bloodsucker):player} sucked blood from {ToPrettyString(victim):target}"); _audio.PlayPvs("/Audio/Items/drink.ogg", bloodsucker); - _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); - _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked", ("target", victim)), bloodsucker, bloodsucker, Shared.Popups.PopupType.Medium); + _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked-victim", ("sucker", bloodsucker)), victim, victim, PopupType.LargeCaution); + _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked", ("target", victim)), bloodsucker, bloodsucker, PopupType.Medium); EnsureComp(victim); } + } } diff --git a/Content.Shared/_DV/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs b/Content.Shared/_DV/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs index 3f473de73b0..ac94804639f 100644 --- a/Content.Shared/_DV/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs +++ b/Content.Shared/_DV/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs @@ -4,7 +4,7 @@ namespace Content.Shared._DV.Vampire.Injector /// /// Item that gives a bloodsucker injection glands (for poison, usually) /// - public sealed partial class BloodSuckerGlandInjectorComponent : Component + public partial class BloodSuckerGlandInjectorComponent { public bool Used = false; From 3103a87b6606d31fee0136faac566dd2846f00d6 Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:16:41 -0500 Subject: [PATCH 26/26] a --- .../_DV/Vampire/BloodSuckerSystem.cs | 70 +++++++++---------- .../_DV/Vampire/BloodSuckerSystem.cs | 2 +- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Content.Server/_DV/Vampire/BloodSuckerSystem.cs b/Content.Server/_DV/Vampire/BloodSuckerSystem.cs index d66e07c28d7..78f865a7418 100644 --- a/Content.Server/_DV/Vampire/BloodSuckerSystem.cs +++ b/Content.Server/_DV/Vampire/BloodSuckerSystem.cs @@ -122,50 +122,50 @@ public void StartSuckDoAfter(EntityUid bloodsucker, EntityUid victim, BloodSucke public bool TrySuck(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodsuckerComp = null) - { - var sharedBloodSuckerSystem = EntitySystem.Get(); +{ + var sharedBloodSuckerSystem = EntitySystem.Get(); - if (!Resolve(bloodsucker, ref bloodsuckerComp)) - return false; - if (!TryValidateVictim(victim)) - return false; + if (!Resolve(bloodsucker, ref bloodsuckerComp)) + return false; + if (!TryValidateVictim(victim)) + return false; - if (!TryGetBloodsuckerStomach(bloodsucker, out var stomach)) - return false; - if (!sharedBloodSuckerSystem.TryValidateSolution(bloodsucker)) - return false; + if (!TryGetBloodsuckerStomach(bloodsucker, out var stomach)) + return false; + if (!sharedBloodSuckerSystem.TryValidateSolution(bloodsucker)) + return false; - sharedBloodSuckerSystem.PlayBloodSuckEffects(bloodsucker, victim); - return CompleteBloodSuck(bloodsucker, victim, stomach, bloodsuckerComp); - } + sharedBloodSuckerSystem.PlayBloodSuckEffects(bloodsucker, victim); + return CompleteBloodSuck(bloodsucker, victim, stomach, bloodsuckerComp); +} - private bool TryValidateVictim(EntityUid victim) - { - if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) - return false; - return _bloodstreamSystem.GetBloodLevelPercentage(victim, bloodstream) != 0.0f; - } +private bool TryValidateVictim(EntityUid victim) +{ + if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) + return false; + return _bloodstreamSystem.GetBloodLevelPercentage(victim, bloodstream) != 0.0f; +} - private bool TryGetBloodsuckerStomach(EntityUid bloodsucker, out StomachComponent stomach) - { - stomach = _bodySystem.GetBodyOrganEntityComps(bloodsucker).FirstOrDefault(); - return true; - } +private bool TryGetBloodsuckerStomach(EntityUid bloodsucker, out StomachComponent stomach) +{ + stomach = _bodySystem.GetBodyOrganEntityComps(bloodsucker).FirstOrDefault(); + return true; +} - private bool CompleteBloodSuck(EntityUid bloodsucker, EntityUid victim, StomachComponent stomach, BloodSuckerComponent bloodsuckerComp) - { - if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) - return false; +private bool CompleteBloodSuck(EntityUid bloodsucker, EntityUid victim, StomachComponent stomach, BloodSuckerComponent bloodsuckerComp) +{ + if (!TryComp(victim, out var bloodstream) || bloodstream.BloodSolution == null) + return false; - var extractedBlood = _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSuck); - _stomachSystem.TryTransferSolution(bloodsucker, extractedBlood, stomach); + var extractedBlood = _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSuck); + _stomachSystem.TryTransferSolution(bloodsucker, extractedBlood, stomach); - DamageSpecifier damage = new(); - damage.DamageDict.Add("Piercing", 1); - _damageableSystem.TryChangeDamage(victim, damage, true); + DamageSpecifier damage = new(); + damage.DamageDict.Add("Piercing", 1); + _damageableSystem.TryChangeDamage(victim, damage, true); - return true; - } + return true; +} } } diff --git a/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs b/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs index 8e32db925d1..6e57c7b2b79 100644 --- a/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs +++ b/Content.Shared/_DV/Vampire/BloodSuckerSystem.cs @@ -54,7 +54,7 @@ public bool TryValidateSolution(EntityUid bloodsucker) return false; } - public void PlayBloodSuckEffects(EntityUid bloodsucker, EntityUid victim) + private void PlayBloodSuckEffects(EntityUid bloodsucker, EntityUid victim) { _adminLogger.Add(LogType.MeleeHit, LogImpact.Medium, $"{ToPrettyString(bloodsucker):player} sucked blood from {ToPrettyString(victim):target}"); _audio.PlayPvs("/Audio/Items/drink.ogg", bloodsucker);