Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diona Nymphs & Splitting #24630

Merged
merged 11 commits into from
Feb 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions Content.Server/Atmos/EntitySystems/FlammableSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
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;
Expand All @@ -20,6 +21,7 @@
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;
Expand Down Expand Up @@ -73,6 +75,8 @@ public override void Initialize()
SubscribeLocalEvent<IgniteOnMeleeHitComponent, MeleeHitEvent>(OnMeleeHit);

SubscribeLocalEvent<ExtinguishOnInteractComponent, ActivateInWorldEvent>(OnExtinguishActivateInWorld);

SubscribeLocalEvent<IgniteOnHeatDamageComponent, DamageChangedEvent>(OnDamageChanged);
}

private void OnMeleeHit(EntityUid uid, IgniteOnMeleeHitComponent component, MeleeHitEvent args)
Expand Down Expand Up @@ -318,6 +322,31 @@ public void Ignite(EntityUid uid, EntityUid ignitionSource, FlammableComponent?
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)
{
Expand Down
15 changes: 15 additions & 0 deletions Content.Server/Damage/Components/IgniteOnHeatDamageComponent.cs
Original file line number Diff line number Diff line change
@@ -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;
}
2 changes: 1 addition & 1 deletion Content.Server/Silicons/Borgs/BorgSystem.Modules.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
8 changes: 8 additions & 0 deletions Content.Shared/Mind/Components/IsDeadICComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Content.Shared.Mind.Components;

[RegisterComponent]
public sealed partial class IsDeadICComponent : Component
{
}


21 changes: 21 additions & 0 deletions Content.Shared/Mind/IsDeadICSystem.cs
Original file line number Diff line number Diff line change
@@ -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 changes: 30 additions & 0 deletions Content.Shared/Species/Components/GibActionComponent.cs
Original file line number Diff line number Diff line change
@@ -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 changes: 24 additions & 0 deletions Content.Shared/Species/Components/NymphComponent.cs
Original file line number Diff line number Diff line change
@@ -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 changes: 48 additions & 0 deletions Content.Shared/Species/Components/ReformComponent.cs
Original file line number Diff line number Diff line change
@@ -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 changes: 61 additions & 0 deletions Content.Shared/Species/Systems/GibActionSystem.cs
Original file line number Diff line number Diff line change
@@ -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 changes: 41 additions & 0 deletions Content.Shared/Species/Systems/NymphSystem.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
Loading
Loading