]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Diona Nymphs & Splitting (#24630)
authorLankLTE <135308300+LankLTE@users.noreply.github.com>
Sat, 17 Feb 2024 02:54:44 +0000 (18:54 -0800)
committerGitHub <noreply@github.com>
Sat, 17 Feb 2024 02:54:44 +0000 (18:54 -0800)
* Porting & implementation

* Fix two stupid errors

* Human not humans

* fix audio path

* Fix test fails & update cooldown

* Work on reviews & test fail

* Rework nymph organ system.

* Make the nymph organs nospawn.

* IsDeadIC

27 files changed:
Content.Server/Atmos/EntitySystems/FlammableSystem.cs
Content.Server/Damage/Components/IgniteOnHeatDamageComponent.cs [new file with mode: 0644]
Content.Server/Silicons/Borgs/BorgSystem.Modules.cs
Content.Shared/Mind/Components/IsDeadICComponent.cs [new file with mode: 0644]
Content.Shared/Mind/IsDeadICSystem.cs [new file with mode: 0644]
Content.Shared/Species/Components/GibActionComponent.cs [new file with mode: 0644]
Content.Shared/Species/Components/NymphComponent.cs [new file with mode: 0644]
Content.Shared/Species/Components/ReformComponent.cs [new file with mode: 0644]
Content.Shared/Species/Systems/GibActionSystem.cs [new file with mode: 0644]
Content.Shared/Species/Systems/NymphSystem.cs [new file with mode: 0644]
Content.Shared/Species/Systems/ReformSystem.cs [new file with mode: 0644]
Resources/Audio/Animals/attributions.yml
Resources/Audio/Animals/nymph_chirp.ogg [new file with mode: 0644]
Resources/Locale/en-US/actions/actions/diona.ftl [new file with mode: 0644]
Resources/Locale/en-US/interaction/interaction-popup-component.ftl
Resources/Prototypes/Actions/diona.yml [new file with mode: 0644]
Resources/Prototypes/Body/Organs/diona.yml
Resources/Prototypes/Body/Prototypes/Animal/nymph.yml [new file with mode: 0644]
Resources/Prototypes/Body/Prototypes/diona.yml
Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
Resources/Prototypes/Entities/Mobs/Player/diona.yml
Resources/Prototypes/Entities/Mobs/Species/diona.yml
Resources/Textures/Mobs/Animals/nymph.rsi/icon.png [new file with mode: 0644]
Resources/Textures/Mobs/Animals/nymph.rsi/meta.json [new file with mode: 0644]
Resources/Textures/Mobs/Animals/nymph.rsi/nymph.png [new file with mode: 0644]
Resources/Textures/Mobs/Animals/nymph.rsi/nymph_dead.png [new file with mode: 0644]
Resources/Textures/Mobs/Animals/nymph.rsi/nymph_sleep.png [new file with mode: 0644]

index cb1cb9bc15022008cc54d897c0caddda86bab057..53fcb720766f8ae98eb8b6720e063d9718afe778 100644 (file)
@@ -4,6 +4,7 @@ using Content.Server.IgnitionSource;
 using Content.Server.Stunnable;
 using Content.Server.Temperature.Components;
 using Content.Server.Temperature.Systems;
+using Content.Server.Damage.Components;
 using Content.Shared.ActionBlocker;
 using Content.Shared.Alert;
 using Content.Shared.Atmos;
@@ -20,6 +21,7 @@ using Content.Shared.Throwing;
 using Content.Shared.Timing;
 using Content.Shared.Toggleable;
 using Content.Shared.Weapons.Melee.Events;
+using Content.Shared.FixedPoint;
 using Robust.Server.Audio;
 using Robust.Shared.Physics.Components;
 using Robust.Shared.Physics.Events;
@@ -73,6 +75,8 @@ namespace Content.Server.Atmos.EntitySystems
             SubscribeLocalEvent<IgniteOnMeleeHitComponent, MeleeHitEvent>(OnMeleeHit);
 
             SubscribeLocalEvent<ExtinguishOnInteractComponent, ActivateInWorldEvent>(OnExtinguishActivateInWorld);
+
+            SubscribeLocalEvent<IgniteOnHeatDamageComponent, DamageChangedEvent>(OnDamageChanged);
         }
 
         private void OnMeleeHit(EntityUid uid, IgniteOnMeleeHitComponent component, MeleeHitEvent args)
@@ -318,6 +322,31 @@ namespace Content.Server.Atmos.EntitySystems
             UpdateAppearance(uid, flammable);
         }
 
+        private void OnDamageChanged(EntityUid uid, IgniteOnHeatDamageComponent component, DamageChangedEvent args)
+        {
+            // Make sure the entity is flammable
+            if (!TryComp<FlammableComponent>(uid, out var flammable))
+                return;
+
+            // Make sure the damage delta isn't null
+            if (args.DamageDelta == null)
+                return;
+
+            // Check if its' taken any heat damage, and give the value
+            if (args.DamageDelta.DamageDict.TryGetValue("Heat", out FixedPoint2 value))
+            {
+                // Make sure the value is greater than the threshold
+                if(value <= component.Threshold)
+                    return;
+
+                // Ignite that sucker
+                flammable.FireStacks += component.FireStacks;
+                Ignite(uid, uid, flammable);
+            }
+
+
+        }
+
         public void Resist(EntityUid uid,
             FlammableComponent? flammable = null)
         {
diff --git a/Content.Server/Damage/Components/IgniteOnHeatDamageComponent.cs b/Content.Server/Damage/Components/IgniteOnHeatDamageComponent.cs
new file mode 100644 (file)
index 0000000..81018f5
--- /dev/null
@@ -0,0 +1,15 @@
+using Content.Shared.Damage;
+using Content.Shared.FixedPoint;
+
+namespace Content.Server.Damage.Components;
+
+[RegisterComponent]
+public sealed partial class IgniteOnHeatDamageComponent : Component
+{
+    [DataField("fireStacks")]
+    public float FireStacks = 1f;
+
+    // The minimum amount of damage taken to apply fire stacks
+    [DataField("threshold")]
+    public FixedPoint2 Threshold = 15;
+}
index a89a101845cff1d76aafd48e8d9185e1546f979a..cc57c34c4754b1458a68aed9e0077dd97cca148a 100644 (file)
@@ -1,4 +1,4 @@
-using System.Linq;
+using System.Linq;
 using Content.Shared.Hands.Components;
 using Content.Shared.Interaction.Components;
 using Content.Shared.Silicons.Borgs.Components;
diff --git a/Content.Shared/Mind/Components/IsDeadICComponent.cs b/Content.Shared/Mind/Components/IsDeadICComponent.cs
new file mode 100644 (file)
index 0000000..d62743d
--- /dev/null
@@ -0,0 +1,8 @@
+namespace Content.Shared.Mind.Components;
+
+[RegisterComponent]
+public sealed partial class IsDeadICComponent : Component
+{
+}
+
+
diff --git a/Content.Shared/Mind/IsDeadICSystem.cs b/Content.Shared/Mind/IsDeadICSystem.cs
new file mode 100644 (file)
index 0000000..6716f38
--- /dev/null
@@ -0,0 +1,21 @@
+using Content.Shared.Mind.Components;
+
+namespace Content.Shared.Mind;
+
+/// <summary>
+/// This marks any entity with the component as dead
+/// for stuff like objectives & round-end
+/// used for nymphs & reformed diona.
+/// </summary>
+public sealed class IsDeadICSystem : EntitySystem
+{
+    public override void Initialize()
+    {
+        SubscribeLocalEvent<IsDeadICComponent, GetCharactedDeadIcEvent>(OnGetDeadIC);
+    }
+
+    private void OnGetDeadIC(EntityUid uid, IsDeadICComponent component, ref GetCharactedDeadIcEvent args)
+    {
+        args.Dead = true;
+    }
+}
diff --git a/Content.Shared/Species/Components/GibActionComponent.cs b/Content.Shared/Species/Components/GibActionComponent.cs
new file mode 100644 (file)
index 0000000..bed94f0
--- /dev/null
@@ -0,0 +1,30 @@
+using Content.Shared.Mobs;
+using Robust.Shared.Prototypes;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Species.Components;
+
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class GibActionComponent : Component
+{
+    /// <summary>
+    /// The action to use.
+    /// </summary>
+    [DataField("actionPrototype", required: true)]
+    public EntProtoId ActionPrototype;
+
+    [DataField, AutoNetworkedField] 
+    public EntityUid? ActionEntity;
+
+    /// <summary>
+    /// What mob states the action will appear in
+    /// </summary>
+    [DataField("allowedStates"), ViewVariables(VVAccess.ReadWrite)]
+    public List<MobState> AllowedStates = new();
+
+    /// <summary>
+    /// The text that appears when attempting to split.
+    /// </summary>
+    [DataField("popupText")]
+    public string PopupText = "diona-gib-action-use";
+}
diff --git a/Content.Shared/Species/Components/NymphComponent.cs b/Content.Shared/Species/Components/NymphComponent.cs
new file mode 100644 (file)
index 0000000..e8fe2f3
--- /dev/null
@@ -0,0 +1,24 @@
+using Robust.Shared.Prototypes;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Species.Components;
+/// <summary>
+/// This will replace one entity with another entity when it is removed from a body part.
+/// Obviously hyper-specific. If you somehow find another use for this, good on you. 
+/// </summary>
+
+[RegisterComponent, NetworkedComponent]
+public sealed partial class NymphComponent : Component
+{
+    /// <summary>
+    /// The entity to replace the organ with.
+    /// </summary>
+    [DataField(required: true)]
+    public EntProtoId EntityPrototype = default!;
+
+    /// <summary>
+    /// Whether to transfer the mind to this new entity.
+    /// </summary>
+    [DataField]
+    public bool TransferMind = false;
+}
diff --git a/Content.Shared/Species/Components/ReformComponent.cs b/Content.Shared/Species/Components/ReformComponent.cs
new file mode 100644 (file)
index 0000000..724c9dc
--- /dev/null
@@ -0,0 +1,48 @@
+    using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Species.Components;
+
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class ReformComponent : Component
+{
+    /// <summary>
+    /// The action to use.
+    /// </summary>
+    [DataField(required: true)]
+    public EntProtoId ActionPrototype = default!;
+
+    [DataField, AutoNetworkedField] 
+    public EntityUid? ActionEntity;
+
+    /// <summary>
+    /// How long it will take to reform
+    /// </summary>
+    [DataField(required: true)]
+    public float ReformTime = 0;
+
+    /// <summary>
+    /// Whether or not the entity should start with a cooldown
+    /// </summary>
+    [DataField]
+    public bool StartDelayed = true;
+
+    /// <summary>
+    /// Whether or not the entity should be stunned when reforming at all
+    /// </summary>
+    [DataField]
+    public bool ShouldStun = true;
+
+    /// <summary>
+    /// The text that appears when attempting to reform
+    /// </summary>
+    [DataField(required: true)]
+    public string PopupText;
+
+    /// <summary>
+    /// The mob that our entity will reform into
+    /// </summary>
+    [DataField(required: true)]
+    public EntProtoId ReformPrototype { get; private set; }
+}
diff --git a/Content.Shared/Species/Systems/GibActionSystem.cs b/Content.Shared/Species/Systems/GibActionSystem.cs
new file mode 100644 (file)
index 0000000..bd7cb6b
--- /dev/null
@@ -0,0 +1,61 @@
+using Content.Shared.Species.Components;
+using Content.Shared.Actions;
+using Content.Shared.Body.Systems;
+using Content.Shared.Mobs;
+using Content.Shared.Mobs.Components;
+using Content.Shared.Popups;
+using Robust.Shared.Prototypes;
+
+
+namespace Content.Shared.Species;
+
+public sealed partial class GibActionSystem : EntitySystem
+{
+    [Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
+    [Dependency] private readonly SharedBodySystem _bodySystem = default!;
+    [Dependency] private readonly IPrototypeManager _protoManager = default!;
+    [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<GibActionComponent, MobStateChangedEvent>(OnMobStateChanged);
+        SubscribeLocalEvent<GibActionComponent, GibActionEvent>(OnGibAction);
+    }
+
+    private void OnMobStateChanged(EntityUid uid, GibActionComponent comp, MobStateChangedEvent args)
+    {
+        // When the mob changes state, check if they're dead and give them the action if so. 
+        if (!TryComp<MobStateComponent>(uid, out var mobState))
+            return;
+
+        if (!_protoManager.TryIndex<EntityPrototype>(comp.ActionPrototype, out var actionProto))
+            return;
+
+
+        foreach (var allowedState in comp.AllowedStates)
+        {
+            if(allowedState == mobState.CurrentState)
+            {
+                // The mob should never have more than 1 state so I don't see this being an issue
+                _actionsSystem.AddAction(uid, ref comp.ActionEntity, comp.ActionPrototype);
+                return;
+            }
+        }
+
+        // If they aren't given the action, remove it.
+        _actionsSystem.RemoveAction(uid, comp.ActionEntity);
+    }
+    
+    private void OnGibAction(EntityUid uid, GibActionComponent comp, GibActionEvent args)
+    {
+        // When they use the action, gib them.
+        _popupSystem.PopupClient(Loc.GetString(comp.PopupText, ("name", uid)), uid, uid);
+        _bodySystem.GibBody(uid, true);
+    }
+       
+
+
+    public sealed partial class GibActionEvent : InstantActionEvent { } 
+}
diff --git a/Content.Shared/Species/Systems/NymphSystem.cs b/Content.Shared/Species/Systems/NymphSystem.cs
new file mode 100644 (file)
index 0000000..7acbf2e
--- /dev/null
@@ -0,0 +1,41 @@
+using Content.Shared.Species.Components;
+using Content.Shared.Body.Events;
+using Content.Shared.Mind;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Timing;
+
+namespace Content.Shared.Species;
+
+public sealed partial class NymphSystem : EntitySystem
+{
+    [Dependency] protected readonly IPrototypeManager _protoManager = default!;
+    [Dependency] private readonly SharedMindSystem _mindSystem = default!;
+    [Dependency] private readonly IGameTiming _timing = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<NymphComponent, RemovedFromPartInBodyEvent>(OnRemovedFromPart);
+    }
+
+    private void OnRemovedFromPart(EntityUid uid, NymphComponent comp, RemovedFromPartInBodyEvent args)
+    {
+        if (!_timing.IsFirstTimePredicted)
+            return;
+
+        if (TerminatingOrDeleted(uid) || TerminatingOrDeleted(args.OldBody))
+            return;
+
+        if (!_protoManager.TryIndex<EntityPrototype>(comp.EntityPrototype, out var entityProto))
+            return;
+
+        var coords = Transform(uid).Coordinates;
+        var nymph = EntityManager.SpawnEntity(entityProto.ID, coords);
+
+        if (comp.TransferMind == true && _mindSystem.TryGetMind(args.OldBody, out var mindId, out var mind))
+            _mindSystem.TransferTo(mindId, nymph, mind: mind);
+
+        EntityManager.QueueDeleteEntity(uid);
+    }
+}
diff --git a/Content.Shared/Species/Systems/ReformSystem.cs b/Content.Shared/Species/Systems/ReformSystem.cs
new file mode 100644 (file)
index 0000000..a013a7f
--- /dev/null
@@ -0,0 +1,108 @@
+using Content.Shared.Species.Components;
+using Content.Shared.Actions;
+using Content.Shared.DoAfter;
+using Content.Shared.Popups;
+using Content.Shared.Stunnable;
+using Content.Shared.Mind;
+using Content.Shared.Humanoid;
+using Robust.Shared.Network;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization;
+using Robust.Shared.Timing;
+using Robust.Shared.Serialization.Manager;
+
+namespace Content.Shared.Species;
+
+public sealed partial class ReformSystem : EntitySystem
+{
+    [Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
+    [Dependency] private readonly INetManager _netMan = default!;
+    [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
+    [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
+    [Dependency] private readonly IPrototypeManager _protoManager = default!;
+    [Dependency] private readonly SharedStunSystem _stunSystem = default!;
+    [Dependency] private readonly IGameTiming _gameTiming = default!;
+    [Dependency] private readonly SharedMindSystem _mindSystem = default!;
+    [Dependency] private readonly MetaDataSystem _metaData = default!;
+    [Dependency] private readonly ISerializationManager _serializationManager = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<ReformComponent, MapInitEvent>(OnMapInit);
+        SubscribeLocalEvent<ReformComponent, ComponentShutdown>(OnCompRemove);
+
+        SubscribeLocalEvent<ReformComponent, ReformEvent>(OnReform);
+        SubscribeLocalEvent<ReformComponent, ReformDoAfterEvent>(OnDoAfter);
+    }
+
+    private void OnMapInit(EntityUid uid, ReformComponent comp, MapInitEvent args)
+    {
+        // When the map is initialized, give them the action
+        if (comp.ActionPrototype != default && !_protoManager.TryIndex<EntityPrototype>(comp.ActionPrototype, out var actionProto))
+            return;
+
+        _actionsSystem.AddAction(uid, ref comp.ActionEntity, out var reformAction, comp.ActionPrototype);
+
+        // See if the action should start with a delay, and give it that starting delay if so.
+        if (comp.StartDelayed && reformAction != null && reformAction.UseDelay != null)
+        {
+            var start = _gameTiming.CurTime;
+            var end = _gameTiming.CurTime + reformAction.UseDelay.Value;
+
+            _actionsSystem.SetCooldown(comp.ActionEntity!.Value, start, end);
+        }
+    }
+
+    private void OnCompRemove(EntityUid uid, ReformComponent comp, ComponentShutdown args)
+    {
+        _actionsSystem.RemoveAction(uid, comp.ActionEntity);
+    }
+
+    private void OnReform(EntityUid uid, ReformComponent comp, ReformEvent args)
+    {
+        // Stun them when they use the action for the amount of reform time.
+        if (comp.ShouldStun)
+            _stunSystem.TryStun(uid, TimeSpan.FromSeconds(comp.ReformTime), true);
+        _popupSystem.PopupClient(Loc.GetString(comp.PopupText, ("name", uid)), uid, uid);
+
+        // Create a doafter & start it
+        var doAfter = new DoAfterArgs(EntityManager, uid, comp.ReformTime, new ReformDoAfterEvent(), uid)
+        {
+            BreakOnUserMove = true,
+            BlockDuplicate = true,
+            BreakOnDamage = true,
+            CancelDuplicate = true,
+            RequireCanInteract = false,
+        };
+
+        _doAfterSystem.TryStartDoAfter(doAfter);
+        args.Handled = true;
+    }
+
+    private void OnDoAfter(EntityUid uid, ReformComponent comp, ReformDoAfterEvent args)
+    {
+        if (args.Cancelled || args.Handled || comp.Deleted)
+            return;
+
+        if (_netMan.IsClient)
+            return;
+
+        // Spawn a new entity
+        // This is, to an extent, taken from polymorph. I don't use polymorph for various reasons- most notably that this is permanent. 
+        var child = Spawn(comp.ReformPrototype, Transform(uid).Coordinates);
+
+        // This transfers the mind to the new entity
+        if (_mindSystem.TryGetMind(uid, out var mindId, out var mind))
+                _mindSystem.TransferTo(mindId, child, mind: mind);
+
+        // Delete the old entity
+        QueueDel(uid);
+    }
+
+    public sealed partial class ReformEvent : InstantActionEvent { } 
+    
+    [Serializable, NetSerializable]
+    public sealed partial class ReformDoAfterEvent : SimpleDoAfterEvent { }
+}
index c9c20473c21e969829bee8ae39764c68412bddb1..c34832a807a786074b148aea6d06f5ad2c3bc26a 100644 (file)
 - files: ["dog_bark3.ogg"]
   license: "CC0-1.0"
   copyright: "Audio is recorded/created by KFerentchak 'FreeSound.org'. The original audio was trimmed and renamed"
-  source: "https://freesound.org/people/KFerentchak/sounds/235912/"
\ No newline at end of file
+  source: "https://freesound.org/people/KFerentchak/sounds/235912/"
+  
+- files: ["nymph_chirp.ogg"]
+  license: "CC-BY-SA-3.0"
+  copyright: "Taken from ParadiseSS13"
+  source: "https://github.com/ParadiseSS13/Paradise/commit/a34f1054cef5a44a67fdac3b67b811137c6071dd"
+  
\ No newline at end of file
diff --git a/Resources/Audio/Animals/nymph_chirp.ogg b/Resources/Audio/Animals/nymph_chirp.ogg
new file mode 100644 (file)
index 0000000..e0e573d
Binary files /dev/null and b/Resources/Audio/Animals/nymph_chirp.ogg differ
diff --git a/Resources/Locale/en-US/actions/actions/diona.ftl b/Resources/Locale/en-US/actions/actions/diona.ftl
new file mode 100644 (file)
index 0000000..3745e6f
--- /dev/null
@@ -0,0 +1,3 @@
+diona-gib-action-use = {$name} splits apart in an instant!
+
+diona-reform-attempt = {$name} attempts to reform!
\ No newline at end of file
index e18d85df2ebb2e098b98eed37c4a2b4357ece8e3..bb56233ff14f2a02eb5abcc32edfc731f55c0f82 100644 (file)
@@ -31,6 +31,7 @@ petting-success-bear = You reluctantly pet {THE($target)} on {POSS-ADJ($target)}
 petting-success-slimes = You pet {THE($target)} on {POSS-ADJ($target)} mucous surface.
 petting-success-snake = You pet {THE($target)} on {POSS-ADJ($target)} scaly large head.
 petting-success-monkey = You pet {THE($target)} on {POSS-ADJ($target)} mischevious little head.
+petting-success-nymph = You pet {THE($target)} on {POSS-ADJ($target)} wooden little head.
 
 petting-failure-generic = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} aloof towards you.
 
@@ -51,6 +52,7 @@ petting-failure-dragon = You raise your hand, but as {THE($target)} roars, you d
 petting-failure-hamster = You reach out to pet {THE($target)}, but {SUBJECT($target)} attempts to bite your finger and only your quick reflexes save you from an almost fatal injury.
 petting-failure-bear = You reach out to pet {THE($target)}, but {SUBJECT($target)} growls, making you think twice.
 petting-failure-monkey = You reach out to pet {THE($target)}, but {SUBJECT($target)} almost bites your fingers!
+petting-failure-nymph = You reach out to pet {THE($target)}, but {POSS-ADJ($target)} moves their branches away.
 petting-failure-shadow = You're trying to pet {THE($target)}, but your hand passes through the cold darkness of his body.
 
 ## Petting silicons
diff --git a/Resources/Prototypes/Actions/diona.yml b/Resources/Prototypes/Actions/diona.yml
new file mode 100644 (file)
index 0000000..ac65d68
--- /dev/null
@@ -0,0 +1,21 @@
+- type: entity
+  id: DionaGibAction
+  name: Gib Yourself!
+  description: Split apart into 3 nymphs.
+  noSpawn: true
+  components:
+  - type: InstantAction
+    icon: Mobs/Species/Diona/organs.rsi/brain.png
+    event: !type:GibActionEvent {}
+    checkCanInteract: false
+
+- type: entity
+  id: DionaReformAction
+  name: Reform
+  description: Reform back into a whole Diona.
+  noSpawn: true
+  components:
+  - type: InstantAction
+    icon: Mobs/Species/Diona/parts.rsi/full.png
+    event: !type:ReformEvent {}
+    useDelay: 300 # Once every 10 minutes. Keep them dead for a fair bit before reforming
index 282bb224d81bdc295e4e3bc2d2d2246fae43f4b5..23df396dd1ee850d0184dbc4417b8cd27d8db3f9 100644 (file)
         reagents:
         - ReagentId: UncookedAnimalProteins
           Quantity: 5
-  - type: Brain
-  - type: InputMover
-  - type: Examiner
-  - type: Lung #lungs in they head. why they there tho?
-  - type: Metabolizer
-    removeEmpty: true
-    solutionOnBody: false
-    solution: "Lung"
-    metabolizerTypes: [ Plant ]
-    groups:
-    - id: Gas
-      rateModifier: 100.0
 
 - type: entity
   id: OrganDionaEyes
       - id: Narcotic
       - id: Alcohol
         rateModifier: 0.1
+
+- type: entity
+  id: OrganDionaLungs
+  parent: BaseDionaOrgan
+  name: lungs
+  description: "Filters oxygen from an atmosphere, which is then sent into the bloodstream to be used as an electron carrier."
+  components:
+  - type: Sprite
+    sprite: Mobs/Species/Human/organs.rsi
+    layers:
+      - state: lung-l
+      - state: lung-r
+  - type: Lung 
+  - type: Metabolizer
+    removeEmpty: true
+    solutionOnBody: false
+    solution: "Lung"
+    metabolizerTypes: [ Plant ]
+    groups:
+    - id: Gas
+      rateModifier: 100.0
+  - type: SolutionContainerManager
+    solutions:
+      organ:
+        maxVol: 10
+        reagents:
+        - ReagentId: Nutriment
+          Quantity: 10
+      Lung:
+        maxVol: 100
+        canReact: False
+
+# Organs that turn into nymphs on removal
+- type: entity
+  id: OrganDionaBrainNymph
+  parent: OrganDionaBrain
+  noSpawn: true
+  name: brain
+  description: "The source of incredible, unending intelligence. Honk."
+  components:
+  - type: Brain
+  - type: Nymph # This will make the organs turn into a nymph when they're removed. 
+    entityPrototype: OrganDionaNymphBrain
+    transferMind: true
+
+- type: entity
+  id: OrganDionaStomachNymph
+  parent: OrganDionaStomach
+  noSpawn: true
+  name: stomach
+  description: "Gross. This is hard to stomach."
+  components:
+  - type: Nymph
+    entityPrototype: OrganDionaNymphStomach
+
+- type: entity
+  id: OrganDionaLungsNymph
+  parent: OrganDionaLungs
+  noSpawn: true
+  name: lungs
+  description: "Filters oxygen from an atmosphere, which is then sent into the bloodstream to be used as an electron carrier."
+  components:
+  - type: Nymph
+    entityPrototype: OrganDionaNymphLungs
+
+# Nymphs that the organs will turn into
+- type: entity
+  id: OrganDionaNymphBrain
+  parent: MobDionaNymph
+  noSpawn: true
+  name: diona nymph
+  suffix: Brain
+  description: Contains the brain of a formerly fully-formed Diona. Killing this would kill the Diona forever. You monster.
+  components:
+  - type: IsDeadIC
+  - type: Body
+    prototype: AnimalNymphBrain
+
+- type: entity
+  id: OrganDionaNymphStomach
+  parent: MobDionaNymph
+  noSpawn: true
+  name: diona nymph
+  suffix: Stomach
+  description: Contains the stomach of a formerly fully-formed Diona. It doesn't taste any better for it. 
+  components:
+  - type: IsDeadIC
+  - type: Body
+    prototype: AnimalNymphStomach
+
+- type: entity
+  id: OrganDionaNymphLungs
+  parent: MobDionaNymph
+  noSpawn: true
+  name: diona nymph
+  suffix: Lungs
+  description: Contains the lungs of a formerly fully-formed Diona. Breathtaking. 
+  components:
+  - type: IsDeadIC
+  - type: Body
+    prototype: AnimalNymphLungs
diff --git a/Resources/Prototypes/Body/Prototypes/Animal/nymph.yml b/Resources/Prototypes/Body/Prototypes/Animal/nymph.yml
new file mode 100644 (file)
index 0000000..21aafe2
--- /dev/null
@@ -0,0 +1,66 @@
+- type: body
+  id: AnimalNymphBrain
+  name: "nymph"
+  root: torso
+  slots:
+    torso:
+      part: TorsoAnimal
+      connections:
+      - legs
+      organs:
+        brain: OrganDionaBrain
+        lungs: OrganAnimalLungs
+        stomach: OrganAnimalStomach
+        liver: OrganAnimalLiver
+        heart: OrganAnimalHeart
+        kidneys: OrganAnimalKidneys
+    legs:
+      part: LegsAnimal
+      connections:
+      - feet
+    feet:
+      part: FeetAnimal
+
+- type: body
+  id: AnimalNymphLungs
+  name: "nymph"
+  root: torso
+  slots:
+    torso:
+      part: TorsoAnimal
+      connections:
+      - legs
+      organs:
+        lungs: OrganDionaLungs
+        stomach: OrganAnimalStomach
+        liver: OrganAnimalLiver
+        heart: OrganAnimalHeart
+        kidneys: OrganAnimalKidneys
+    legs:
+      part: LegsAnimal
+      connections:
+      - feet
+    feet:
+      part: FeetAnimal
+
+- type: body
+  id: AnimalNymphStomach
+  name: "nymph"
+  root: torso
+  slots:
+    torso:
+      part: TorsoAnimal
+      connections:
+      - legs
+      organs:
+        lungs: OrganAnimalLungs
+        stomach: OrganDionaStomach
+        liver: OrganAnimalLiver
+        heart: OrganAnimalHeart
+        kidneys: OrganAnimalKidneys
+    legs:
+      part: LegsAnimal
+      connections:
+      - feet
+    feet:
+      part: FeetAnimal
\ No newline at end of file
index f364d0f800f0486f4e083d908b43b78ce005e4a5..12ca203988cbca5a28981b6dce7d836aef4dba94 100644 (file)
@@ -8,8 +8,7 @@
       connections:
       - torso
       organs:
-        brain: OrganDionaBrain
-        eyes: OrganDionaEyes
+        brain: OrganDionaBrainNymph
     torso:
       part: TorsoDiona
       connections:
@@ -18,7 +17,8 @@
       - right leg
       - left leg
       organs:
-        stomach: OrganDionaStomach
+        stomach: OrganDionaStomachNymph
+        lungs: OrganDionaLungsNymph
     right arm:
       part: RightArmDiona
       connections:
index 1251884965e96b9ea020980b40959e30e077010c..855a2d89c6a51a2368b6c4162171085a47683dcb 100644 (file)
     factions:
     - Passive
 
+- type: entity
+  name: diona nymph
+  parent: SimpleMobBase
+  id: MobDionaNymph
+  description: It's like a cat, only.... branch-ier.
+  components:
+  - type: Sprite
+    drawdepth: Mobs
+    layers:
+    - map: ["enum.DamageStateVisualLayers.Base"]
+      state: nymph
+      sprite: Mobs/Animals/nymph.rsi
+  - type: Physics
+  - type: Fixtures
+    fixtures:
+      fix1:
+        shape:
+          !type:PhysShapeCircle
+          radius: 0.35
+        density: 100 # High, because wood is heavy.
+        mask:
+        - MobMask
+        layer:
+        - MobLayer
+  - type: Inventory
+    speciesId: cat
+    templateId: pet
+  - type: InventorySlots
+  - type: Strippable
+  - type: Bloodstream
+    bloodReagent: Water
+    bloodMaxVolume: 60
+  - type: UserInterface
+    interfaces:
+    - key: enum.StrippingUiKey.Key
+      type: StrippableBoundUserInterface
+  - type: DamageStateVisuals
+    states:
+      Alive:
+        Base: nymph
+      Critical:
+        Base: nymph_sleep
+      Dead:
+        Base: nymph_dead
+  - type: Butcherable
+    spawned:
+    - id: MaterialWoodPlank1
+      amount: 2
+  - type: InteractionPopup
+    successChance: 0.7
+    interactSuccessString: petting-success-nymph
+    interactFailureString: petting-failure-nymph
+    interactSuccessSound:
+      path: /Audio/Animals/nymph_chirp.ogg
+  - type: MobThresholds
+    thresholds:
+      0: Alive
+      30: Critical
+      60: Dead
+  - type: MovementSpeedModifier
+    baseWalkSpeed : 2.5
+    baseSprintSpeed : 4.5
+  - type: Grammar
+    attributes:
+      gender: epicene
+  - type: Speech
+  - type: Tag
+    tags:
+    - VimPilot
+  - type: Reform
+    actionPrototype: DionaReformAction
+    reformTime: 10
+    popupText: diona-reform-attempt
+    reformPrototype: MobDionaReformed
index 4e7bd7e0c98875f85e88e4a148c796c9cb7ff7c0..4153250bbf9b8a9c3936ddcdc72ee35db7f8588f 100644 (file)
       damageRecovery:
         types:
           Asphyxiation: -1.0
+
+# Reformed Diona
+- type: entity
+  parent: MobDiona
+  noSpawn: true
+  id: MobDionaReformed
+  name: Reformed Diona
+  components:
+    - type: IsDeadIC
+    - type: RandomHumanoidAppearance 
\ No newline at end of file
index 6371fb74eb8457466f64d422e809681787d47e75..7f726e2f2cdcd020e8b170ac5942c9de3af46925 100644 (file)
   - type: BodyEmotes
     soundsId: DionaBodyEmotes
   - type: IgnoreKudzu
+  - type: IgniteOnHeatDamage
+    fireStacks: 1
+    threshold: 12
+  - type: GibAction
+    actionPrototype: DionaGibAction
+    allowedStates:
+    - Dead
 
 - type: entity
   parent: BaseSpeciesDummy
diff --git a/Resources/Textures/Mobs/Animals/nymph.rsi/icon.png b/Resources/Textures/Mobs/Animals/nymph.rsi/icon.png
new file mode 100644 (file)
index 0000000..f1b6a79
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/nymph.rsi/icon.png differ
diff --git a/Resources/Textures/Mobs/Animals/nymph.rsi/meta.json b/Resources/Textures/Mobs/Animals/nymph.rsi/meta.json
new file mode 100644 (file)
index 0000000..c6bb6e0
--- /dev/null
@@ -0,0 +1,63 @@
+{
+  "version": 1,
+  "license": "CC-BY-SA-3.0",
+  "copyright": "https://github.com/ParadiseSS13/Paradise/commit/f367d7de199969a5fb5054de44faa5618092f487",
+  "size": {
+    "x": 32,
+    "y": 32
+  },
+  "states": [
+    {
+      "name": "nymph",
+      "directions": 4,
+      "delays": [
+        [
+          0.1,
+          0.1,
+          0.1,
+          0.1,
+          0.1,
+          0.1,
+          0.1
+        ],
+        [
+          0.1,
+          0.1,
+          0.1,
+          0.1,
+          0.1,
+          0.1,
+          0.1
+        ],
+        [
+          0.1,
+          0.1,
+          0.1,
+          0.1,
+          0.1,
+          0.1,
+          0.1
+        ],
+        [
+          0.1,
+          0.1,
+          0.1,
+          0.1,
+          0.1,
+          0.1,
+          0.1
+        ]
+      ]
+    },
+    {
+      "name": "nymph_dead"
+    },
+    {
+      "name": "nymph_sleep",
+      "directions": 4
+    },
+    {
+      "name": "icon"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/Mobs/Animals/nymph.rsi/nymph.png b/Resources/Textures/Mobs/Animals/nymph.rsi/nymph.png
new file mode 100644 (file)
index 0000000..fe79c89
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/nymph.rsi/nymph.png differ
diff --git a/Resources/Textures/Mobs/Animals/nymph.rsi/nymph_dead.png b/Resources/Textures/Mobs/Animals/nymph.rsi/nymph_dead.png
new file mode 100644 (file)
index 0000000..c3371bf
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/nymph.rsi/nymph_dead.png differ
diff --git a/Resources/Textures/Mobs/Animals/nymph.rsi/nymph_sleep.png b/Resources/Textures/Mobs/Animals/nymph.rsi/nymph_sleep.png
new file mode 100644 (file)
index 0000000..4e2055d
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/nymph.rsi/nymph_sleep.png differ