Diona Nymphs & Splitting (#24630)
* 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
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
8
Content.Shared/Mind/Components/IsDeadICComponent.cs
Normal file
8
Content.Shared/Mind/Components/IsDeadICComponent.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Content.Shared.Mind.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class IsDeadICComponent : Component
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
21
Content.Shared/Mind/IsDeadICSystem.cs
Normal file
21
Content.Shared/Mind/IsDeadICSystem.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
30
Content.Shared/Species/Components/GibActionComponent.cs
Normal file
30
Content.Shared/Species/Components/GibActionComponent.cs
Normal file
@@ -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";
|
||||
}
|
||||
24
Content.Shared/Species/Components/NymphComponent.cs
Normal file
24
Content.Shared/Species/Components/NymphComponent.cs
Normal file
@@ -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;
|
||||
}
|
||||
48
Content.Shared/Species/Components/ReformComponent.cs
Normal file
48
Content.Shared/Species/Components/ReformComponent.cs
Normal file
@@ -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; }
|
||||
}
|
||||
61
Content.Shared/Species/Systems/GibActionSystem.cs
Normal file
61
Content.Shared/Species/Systems/GibActionSystem.cs
Normal file
@@ -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 { }
|
||||
}
|
||||
41
Content.Shared/Species/Systems/NymphSystem.cs
Normal file
41
Content.Shared/Species/Systems/NymphSystem.cs
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
108
Content.Shared/Species/Systems/ReformSystem.cs
Normal file
108
Content.Shared/Species/Systems/ReformSystem.cs
Normal file
@@ -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 { }
|
||||
}
|
||||
@@ -131,4 +131,10 @@
|
||||
- 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/"
|
||||
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"
|
||||
|
||||
BIN
Resources/Audio/Animals/nymph_chirp.ogg
Normal file
BIN
Resources/Audio/Animals/nymph_chirp.ogg
Normal file
Binary file not shown.
3
Resources/Locale/en-US/actions/actions/diona.ftl
Normal file
3
Resources/Locale/en-US/actions/actions/diona.ftl
Normal file
@@ -0,0 +1,3 @@
|
||||
diona-gib-action-use = {$name} splits apart in an instant!
|
||||
|
||||
diona-reform-attempt = {$name} attempts to reform!
|
||||
@@ -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
|
||||
|
||||
21
Resources/Prototypes/Actions/diona.yml
Normal file
21
Resources/Prototypes/Actions/diona.yml
Normal file
@@ -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
|
||||
@@ -48,18 +48,6 @@
|
||||
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
|
||||
@@ -102,3 +90,104 @@
|
||||
- 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
|
||||
|
||||
66
Resources/Prototypes/Body/Prototypes/Animal/nymph.yml
Normal file
66
Resources/Prototypes/Body/Prototypes/Animal/nymph.yml
Normal file
@@ -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
|
||||
@@ -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:
|
||||
|
||||
@@ -3099,3 +3099,77 @@
|
||||
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
|
||||
|
||||
@@ -11,3 +11,13 @@
|
||||
damageRecovery:
|
||||
types:
|
||||
Asphyxiation: -1.0
|
||||
|
||||
# Reformed Diona
|
||||
- type: entity
|
||||
parent: MobDiona
|
||||
noSpawn: true
|
||||
id: MobDionaReformed
|
||||
name: Reformed Diona
|
||||
components:
|
||||
- type: IsDeadIC
|
||||
- type: RandomHumanoidAppearance
|
||||
@@ -94,6 +94,13 @@
|
||||
- type: BodyEmotes
|
||||
soundsId: DionaBodyEmotes
|
||||
- type: IgnoreKudzu
|
||||
- type: IgniteOnHeatDamage
|
||||
fireStacks: 1
|
||||
threshold: 12
|
||||
- type: GibAction
|
||||
actionPrototype: DionaGibAction
|
||||
allowedStates:
|
||||
- Dead
|
||||
|
||||
- type: entity
|
||||
parent: BaseSpeciesDummy
|
||||
|
||||
BIN
Resources/Textures/Mobs/Animals/nymph.rsi/icon.png
Normal file
BIN
Resources/Textures/Mobs/Animals/nymph.rsi/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 611 B |
63
Resources/Textures/Mobs/Animals/nymph.rsi/meta.json
Normal file
63
Resources/Textures/Mobs/Animals/nymph.rsi/meta.json
Normal file
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
Resources/Textures/Mobs/Animals/nymph.rsi/nymph.png
Normal file
BIN
Resources/Textures/Mobs/Animals/nymph.rsi/nymph.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
BIN
Resources/Textures/Mobs/Animals/nymph.rsi/nymph_dead.png
Normal file
BIN
Resources/Textures/Mobs/Animals/nymph.rsi/nymph_dead.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 655 B |
BIN
Resources/Textures/Mobs/Animals/nymph.rsi/nymph_sleep.png
Normal file
BIN
Resources/Textures/Mobs/Animals/nymph.rsi/nymph_sleep.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Reference in New Issue
Block a user