Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using Content.Shared.Whitelist;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Goobstation.Common.Damage;

/// <summary>
/// Goobstation

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant to specify, you can already see that it's in Goob module

/// Make entity destroy other entities on interaction
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class DestroyInteractingsComponent : Component
{
#region Logic Handlers
/// <summary>
/// Whitelist entities that this entity can destroy
/// </summary>
[DataField]
public EntityWhitelist? DestroyWhitelist;

/// <summary>
/// Marks entities that can not be destroed by this entity
/// </summary>
[DataField]
public EntityWhitelist? DestroyBlacklist;

/// <summary>
/// Should entity count contacts as interaction
/// </summary>
[DataField]
public bool RespectContacts = false;

/// <summary>
/// Should entity try interaction with item in hand first
/// </summary>
[DataField]
public bool RespectHandInteraction = true;

/// <summary>
/// The colliding fixture
/// </summary>
[DataField]
public string FixtureId = "bzzz";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use a placeholder name, and possibly make this a required: true datafield in case if this component should always destroy colliding entities


#endregion

#region Visuals and Sounds
/// <summary>
/// Sound that should be played on destruction coordinates
/// </summary>
[DataField]
public SoundSpecifier? DestructionSound;

/// <summary>
/// Entity that should instead of destroyed entity
/// </summary>
[DataField(customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string SpawnOnDestruction = string.Empty;
Comment on lines +59 to +60

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use EntProtoId and remove serializer


//TODO:Particles
#endregion
Comment on lines +62 to +63

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the particles please I've already ported them

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Required #78

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using Content.Goobstation.Common.Damage;
using Content.Shared.Destructible;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Weapons.Melee.Events;
using Content.Shared.Whitelist;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Physics.Events;
using Robust.Shared.Timing;

namespace Content.Goobstation.Shared.Damage;

public sealed partial class SharedDestroyInteractinngSystem : EntitySystem

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sealed classes shouldn't have Shared prefix

{
[Dependency] private IGameTiming _timing = default!;
[Dependency] private SharedAudioSystem _audioSystem = default!;
[Dependency] private SharedDestructibleSystem _destructibleSystem = default!;
[Dependency] private SharedHandsSystem _handsSystem = default!;
[Dependency] private EntityWhitelistSystem _whitelistSystem = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<DestroyInteractingsComponent, InteractUsingEvent>(OnInteractUsing);
SubscribeLocalEvent<DestroyInteractingsComponent, InteractHandEvent>(OnInteractHand);
SubscribeLocalEvent<DestroyInteractingsComponent, StartCollideEvent>(OnCollide);
SubscribeLocalEvent<DestroyInteractingsComponent, AttackedEvent>(OnAttacked);
}

private bool TryDestroyEntity(EntityUid entity, Entity<DestroyInteractingsComponent> destructor, out EntityUid? spawned, EntityUid? user = null)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add line breaks

{
spawned = null;
if (!_whitelistSystem.CheckBoth(entity, destructor.Comp.DestroyBlacklist, destructor.Comp.DestroyWhitelist))
return false;

var position = Transform(entity).Coordinates;
if (!_destructibleSystem.DestroyEntity(entity))
return false;

_audioSystem.PlayPredicted(destructor.Comp.DestructionSound, destructor, user);

if (destructor.Comp.SpawnOnDestruction != string.Empty)
spawned = PredictedSpawnAtPosition(destructor.Comp.SpawnOnDestruction, position);

return true;
}

#region Event Handlers
private void OnInteractUsing(Entity<DestroyInteractingsComponent> destructor, ref InteractUsingEvent args)
{
var target = destructor.Comp.RespectHandInteraction ? args.Used : args.User;
args.Handled = TryDestroyEntity(target, destructor, out var spawned, args.User);

if (spawned is not { } spawnedEnt)
return;

_handsSystem.TryPickup(args.User, spawnedEnt, animate: false);
}

private void OnInteractHand(Entity<DestroyInteractingsComponent> destructor, ref InteractHandEvent args)
{
args.Handled = TryDestroyEntity(args.User, destructor, out _, args.User);
}

private void OnCollide(Entity<DestroyInteractingsComponent> destructor, ref StartCollideEvent args)
{
if (destructor.Comp.RespectContacts && destructor.Comp.FixtureId == args.OurFixtureId && args.OtherFixture.Hard && args.OurFixture.Hard)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line breaks

TryDestroyEntity(args.OtherEntity, destructor, out _);
}

private void OnAttacked(Entity<DestroyInteractingsComponent> destructor, ref AttackedEvent args)
{
TryDestroyEntity(args.Used, destructor, out _, user: args.User);
}

#endregion
}
Loading