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 1/4] 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 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 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 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 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 2/4] 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 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 Date: Tue, 14 Jan 2025 23:29:00 -0500 Subject: [PATCH 3/4] 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 4/4] 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.