Basic gibbing (#2973)
* Adds gibbing * Adds adminbused absurd-damage foamblade * Sane parts * BaseOrgan -> BaseMechanism * Do not do random offset on shared, fix killing oneself with click attacks * BaseMechanism -> BaseHumanOrgan -> *stuff* * Account for prediction, again * Add gibbing sound
This commit is contained in:
committed by
GitHub
parent
8def38aed4
commit
12c733654c
@@ -51,39 +51,42 @@ namespace Content.Client.GameObjects.EntitySystems
|
||||
|
||||
var attacker = EntityManager.GetEntity(msg.Attacker);
|
||||
|
||||
var lunge = attacker.EnsureComponent<MeleeLungeComponent>();
|
||||
lunge.SetData(msg.Angle);
|
||||
|
||||
var entity = EntityManager.SpawnEntity(weaponArc.Prototype, attacker.Transform.Coordinates);
|
||||
entity.Transform.LocalRotation = msg.Angle;
|
||||
|
||||
var weaponArcAnimation = entity.GetComponent<MeleeWeaponArcAnimationComponent>();
|
||||
weaponArcAnimation.SetData(weaponArc, msg.Angle, attacker, msg.ArcFollowAttacker);
|
||||
|
||||
// Due to ISpriteComponent limitations, weapons that don't use an RSI won't have this effect.
|
||||
if (EntityManager.TryGetEntity(msg.Source, out var source) && msg.TextureEffect && source.TryGetComponent(out ISpriteComponent sourceSprite)
|
||||
&& sourceSprite.BaseRSI?.Path != null)
|
||||
if (!attacker.Deleted)
|
||||
{
|
||||
var sys = Get<EffectSystem>();
|
||||
var curTime = _gameTiming.CurTime;
|
||||
var effect = new EffectSystemMessage
|
||||
var lunge = attacker.EnsureComponent<MeleeLungeComponent>();
|
||||
lunge.SetData(msg.Angle);
|
||||
|
||||
var entity = EntityManager.SpawnEntity(weaponArc.Prototype, attacker.Transform.Coordinates);
|
||||
entity.Transform.LocalRotation = msg.Angle;
|
||||
|
||||
var weaponArcAnimation = entity.GetComponent<MeleeWeaponArcAnimationComponent>();
|
||||
weaponArcAnimation.SetData(weaponArc, msg.Angle, attacker, msg.ArcFollowAttacker);
|
||||
|
||||
// Due to ISpriteComponent limitations, weapons that don't use an RSI won't have this effect.
|
||||
if (EntityManager.TryGetEntity(msg.Source, out var source) && msg.TextureEffect && source.TryGetComponent(out ISpriteComponent sourceSprite)
|
||||
&& sourceSprite.BaseRSI?.Path != null)
|
||||
{
|
||||
EffectSprite = sourceSprite.BaseRSI.Path.ToString(),
|
||||
RsiState = sourceSprite.LayerGetState(0).Name,
|
||||
Coordinates = attacker.Transform.Coordinates,
|
||||
Color = Vector4.Multiply(new Vector4(255, 255, 255, 125), 1.0f),
|
||||
ColorDelta = Vector4.Multiply(new Vector4(0, 0, 0, -10), 1.0f),
|
||||
Velocity = msg.Angle.ToVec(),
|
||||
Acceleration = msg.Angle.ToVec() * 5f,
|
||||
Born = curTime,
|
||||
DeathTime = curTime.Add(TimeSpan.FromMilliseconds(300f)),
|
||||
};
|
||||
sys.CreateEffect(effect);
|
||||
var sys = Get<EffectSystem>();
|
||||
var curTime = _gameTiming.CurTime;
|
||||
var effect = new EffectSystemMessage
|
||||
{
|
||||
EffectSprite = sourceSprite.BaseRSI.Path.ToString(),
|
||||
RsiState = sourceSprite.LayerGetState(0).Name,
|
||||
Coordinates = attacker.Transform.Coordinates,
|
||||
Color = Vector4.Multiply(new Vector4(255, 255, 255, 125), 1.0f),
|
||||
ColorDelta = Vector4.Multiply(new Vector4(0, 0, 0, -10), 1.0f),
|
||||
Velocity = msg.Angle.ToVec(),
|
||||
Acceleration = msg.Angle.ToVec() * 5f,
|
||||
Born = curTime,
|
||||
DeathTime = curTime.Add(TimeSpan.FromMilliseconds(300f)),
|
||||
};
|
||||
sys.CreateEffect(effect);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var uid in msg.Hits)
|
||||
{
|
||||
if (!EntityManager.TryGetEntity(uid, out var hitEntity))
|
||||
if (!EntityManager.TryGetEntity(uid, out var hitEntity) || hitEntity.Deleted)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Content.Server.Commands.Observer;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.GameObjects.Components.Body;
|
||||
using Content.Shared.GameObjects.Components.Body.Part;
|
||||
using Content.Shared.GameObjects.Components.Damage;
|
||||
using Content.Shared.GameObjects.Components.Mobs.State;
|
||||
using Content.Shared.GameObjects.Components.Movement;
|
||||
using Content.Shared.Utility;
|
||||
using Robust.Server.GameObjects.Components.Container;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Server.Interfaces.Console;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Players;
|
||||
@@ -41,6 +46,7 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
base.OnRemovePart(slot, part);
|
||||
|
||||
_partContainer.ForceRemove(part.Owner);
|
||||
part.Owner.RandomOffset(0.25f);
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
@@ -88,5 +94,29 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
new Ghost().Execute(shell, (IPlayerSession) session, Array.Empty<string>());
|
||||
}
|
||||
}
|
||||
|
||||
public override void Gib(bool gibParts = false)
|
||||
{
|
||||
base.Gib(gibParts);
|
||||
|
||||
EntitySystem.Get<AudioSystem>()
|
||||
.PlayAtCoords(AudioHelpers.GetRandomFileFromSoundCollection("gib"), Owner.Transform.Coordinates,
|
||||
AudioHelpers.WithVariation(0.025f));
|
||||
|
||||
if (Owner.TryGetComponent(out ContainerManagerComponent? container))
|
||||
{
|
||||
foreach (var cont in container.GetAllContainers())
|
||||
{
|
||||
foreach (var ent in cont.ContainedEntities)
|
||||
{
|
||||
cont.ForceRemove(ent);
|
||||
ent.Transform.Coordinates = Owner.Transform.Coordinates;
|
||||
ent.RandomOffset(0.25f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Owner.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ using Content.Shared.GameObjects.Components.Body.Surgery;
|
||||
using Content.Shared.GameObjects.Verbs;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Content.Shared.Utility;
|
||||
using Robust.Server.Console;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.Components.Container;
|
||||
@@ -57,6 +58,7 @@ namespace Content.Server.GameObjects.Components.Body.Part
|
||||
base.OnRemoveMechanism(mechanism);
|
||||
|
||||
_mechanismContainer.Remove(mechanism.Owner);
|
||||
mechanism.Owner.RandomOffset(0.25f);
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects.Components.Body;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class GibBehavior : IThresholdBehavior
|
||||
{
|
||||
private bool _recursive = true;
|
||||
|
||||
public void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
serializer.DataField(ref _recursive, "recursive", true);
|
||||
}
|
||||
|
||||
public void Trigger(IEntity owner, DestructibleSystem system)
|
||||
{
|
||||
if (owner.TryGetComponent(out IBody body))
|
||||
{
|
||||
body.Gib(_recursive);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,7 +79,7 @@ namespace Content.Server.GameObjects.Components.Recycling
|
||||
// Mobs are a special case!
|
||||
if (CanGib(entity))
|
||||
{
|
||||
entity.Delete(); // TODO: Gib
|
||||
entity.GetComponent<IBody>().Gib(true);
|
||||
Bloodstain();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -247,5 +247,10 @@ namespace Content.Shared.GameObjects.Components.Body
|
||||
/// <param name="index">The index to look in.</param>
|
||||
/// <returns>A pair of the part name and body part occupying it.</returns>
|
||||
KeyValuePair<string, IBodyPart> PartAt(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Gibs this body.
|
||||
/// </summary>
|
||||
void Gib(bool gibParts = false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,5 +116,10 @@ namespace Content.Shared.GameObjects.Components.Body.Part
|
||||
/// false otherwise.
|
||||
/// </returns>
|
||||
bool DeleteMechanism(IMechanism mechanism);
|
||||
|
||||
/// <summary>
|
||||
/// Gibs the body part.
|
||||
/// </summary>
|
||||
void Gib();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Shared.GameObjects.Components.Body.Mechanism;
|
||||
using Content.Shared.GameObjects.Components.Body.Surgery;
|
||||
using Content.Shared.Utility;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -313,6 +314,14 @@ namespace Content.Shared.GameObjects.Components.Body.Part
|
||||
protected virtual void OnAddedToBody(IBody body) { }
|
||||
|
||||
protected virtual void OnRemovedFromBody(IBody old) { }
|
||||
|
||||
public virtual void Gib()
|
||||
{
|
||||
foreach (var mechanism in _mechanisms)
|
||||
{
|
||||
RemoveMechanism(mechanism);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Shared.Damage;
|
||||
@@ -11,7 +12,10 @@ using Content.Shared.GameObjects.Components.Body.Template;
|
||||
using Content.Shared.GameObjects.Components.Damage;
|
||||
using Content.Shared.GameObjects.Components.Movement;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Utility;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components.Containers;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -19,6 +23,7 @@ using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using Component = Robust.Shared.GameObjects.Component;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Body
|
||||
{
|
||||
@@ -697,6 +702,17 @@ namespace Content.Shared.GameObjects.Components.Body
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Gib(bool gibParts = false)
|
||||
{
|
||||
foreach (var (_, part) in Parts)
|
||||
{
|
||||
RemovePart(part);
|
||||
|
||||
if (gibParts)
|
||||
part.Gib();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
BIN
Resources/Audio/Effects/gib1.ogg
Normal file
BIN
Resources/Audio/Effects/gib1.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Effects/gib2.ogg
Normal file
BIN
Resources/Audio/Effects/gib2.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Effects/gib3.ogg
Normal file
BIN
Resources/Audio/Effects/gib3.ogg
Normal file
Binary file not shown.
@@ -1,5 +1,24 @@
|
||||
- type: entity
|
||||
id: BaseMechanism
|
||||
parent: BaseItem
|
||||
name: "base mechanism"
|
||||
abstract: true
|
||||
components:
|
||||
- type: Mechanism
|
||||
|
||||
- type: entity
|
||||
id: BaseHumanOrgan
|
||||
parent: BaseMechanism
|
||||
name: "base human organ"
|
||||
abstract: true
|
||||
components:
|
||||
- type: Sprite
|
||||
netsync: false
|
||||
sprite: Mobs/Species/Human/organs.rsi
|
||||
|
||||
- type: entity
|
||||
id: BrainHuman
|
||||
parent: BaseHumanOrgan
|
||||
name: "human brain"
|
||||
description: "The source of incredible, unending intelligence. Honk."
|
||||
components:
|
||||
@@ -16,6 +35,7 @@
|
||||
|
||||
- type: entity
|
||||
id: EyesHuman
|
||||
parent: BaseHumanOrgan
|
||||
name: "human eyes"
|
||||
description: "Ocular organ capable of turning light into a colorful visual."
|
||||
components:
|
||||
@@ -30,6 +50,7 @@
|
||||
|
||||
- type: entity
|
||||
id: HeartHuman
|
||||
parent: BaseHumanOrgan
|
||||
name: "human heart"
|
||||
description: "Pumps blood throughout a body. Essential for any entity with blood."
|
||||
components:
|
||||
@@ -46,6 +67,7 @@
|
||||
|
||||
- type: entity
|
||||
id: LungsHuman
|
||||
parent: BaseHumanOrgan
|
||||
name: "human lungs"
|
||||
description: "Filters oxygen from an atmosphere, which is then sent into the bloodstream to be used as an electron carrier."
|
||||
components:
|
||||
@@ -62,6 +84,7 @@
|
||||
|
||||
- type: entity
|
||||
id: StomachHuman
|
||||
parent: BaseHumanOrgan
|
||||
name: "human stomach"
|
||||
description: "Gross. This is hard to stomach."
|
||||
components:
|
||||
@@ -82,6 +105,7 @@
|
||||
|
||||
- type: entity
|
||||
id: LiverHuman
|
||||
parent: BaseHumanOrgan
|
||||
name: "human liver"
|
||||
description: "Filters impurities out of a bloodstream and provides other important functionality to a human."
|
||||
components:
|
||||
@@ -96,6 +120,7 @@
|
||||
|
||||
- type: entity
|
||||
id: KidneysHuman
|
||||
parent: BaseHumanOrgan
|
||||
name: "human kidneys"
|
||||
description: "Filters toxins out of a bloodstream."
|
||||
components:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# TODO BODY: Part damage
|
||||
- type: entity
|
||||
id: PartHuman
|
||||
parent: BaseItem
|
||||
name: "human body part"
|
||||
abstract: true
|
||||
|
||||
|
||||
@@ -161,6 +161,11 @@
|
||||
0: !type:NormalMobState {}
|
||||
100: !type:CriticalMobState {}
|
||||
200: !type:DeadMobState {}
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
400:
|
||||
behaviors:
|
||||
- !type:GibBehavior { }
|
||||
- type: HeatResistance
|
||||
- type: Appearance
|
||||
visuals:
|
||||
|
||||
@@ -528,7 +528,6 @@
|
||||
- type: Sprite
|
||||
sprite: Objects/Fun/toys.rsi
|
||||
state: foamblade
|
||||
|
||||
- type: MeleeWeapon
|
||||
range: 2.0
|
||||
arcwidth: 0
|
||||
@@ -539,6 +538,15 @@
|
||||
HeldPrefix: foamblade
|
||||
- type: ItemCooldown
|
||||
|
||||
- type: entity
|
||||
name: foamblade
|
||||
parent: FoamBlade
|
||||
id: FoamBladeAdminbus
|
||||
suffix: adminbused
|
||||
components:
|
||||
- type: MeleeWeapon
|
||||
damage: 1000
|
||||
|
||||
# MISC
|
||||
|
||||
- type: entity
|
||||
|
||||
6
Resources/Prototypes/SoundCollections/gib.yml
Normal file
6
Resources/Prototypes/SoundCollections/gib.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
- type: soundCollection
|
||||
id: gib
|
||||
files:
|
||||
- /Audio/Effects/gib1.ogg
|
||||
- /Audio/Effects/gib2.ogg
|
||||
- /Audio/Effects/gib3.ogg
|
||||
@@ -103,6 +103,7 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fluidsynth/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=freepats/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=gamemode/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Gibs/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=godmode/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Grindable/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=hardcode/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
Reference in New Issue
Block a user