Files
wwdpublic/Content.Server/Damage/Systems/DamageOtherOnHitSystem.cs
Skubman b63a41d6e9 Pacification Prevents Throwing Weapons (#1433)
# Description

Prevents entities who are Pacified (through the Pacifist trait or being
a thief) from throwing items that deal damage on hit or embed.

## Technical Details

Two components will prevent throwing if they deal any damage:
`DamageOtherOnHitComponent` and `EmbedPassiveComponent`.

The pacifist check on `EmbeddableProjectileComponent` has been removed,
because just because an item is embeddable does not mean they deal
damage.

## Media

**Throw attempt with the Pacifist trait**

![image](https://github.com/user-attachments/assets/6c439bb3-b41b-4f30-975d-4fa15c2cfa6d)

# Changelog

🆑 Skubman
- fix: Pacified characters (Pacifist trait and thieves) can no longer
throw items that deal throwing damage.

---------

Signed-off-by: VMSolidus <evilexecutive@gmail.com>
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
(cherry picked from commit 71e3c031750db523f8fcccc4a36a61200b1028f2)
2025-01-14 01:31:56 +03:00

69 lines
2.7 KiB
C#

using Content.Shared.Camera;
using Content.Shared.CombatMode.Pacification;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Events;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.Effects;
using Content.Shared.Item.ItemToggle.Components;
using Content.Shared.Mobs.Components;
using Content.Shared.Projectiles;
using Content.Shared.Popups;
using Content.Shared.Throwing;
using Content.Shared.Weapons.Melee;
using Content.Server.Weapons.Melee;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Physics.Components;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server.Damage.Systems
{
public sealed class DamageOtherOnHitSystem : SharedDamageOtherOnHitSystem
{
[Dependency] private readonly DamageExamineSystem _damageExamine = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly StaminaSystem _stamina = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<StaminaComponent, BeforeThrowEvent>(OnBeforeThrow, after: [typeof(PacificationSystem)]);
SubscribeLocalEvent<DamageOtherOnHitComponent, DamageExamineEvent>(OnDamageExamine, after: [typeof(MeleeWeaponSystem)]);
}
private void OnBeforeThrow(EntityUid uid, StaminaComponent component, ref BeforeThrowEvent args)
{
if (args.Cancelled || !TryComp<DamageOtherOnHitComponent>(args.ItemUid, out var damage))
return;
if (component.CritThreshold - component.StaminaDamage <= damage.StaminaCost)
{
args.Cancelled = true;
_popup.PopupEntity(Loc.GetString("throw-no-stamina", ("item", args.ItemUid)), uid, uid);
return;
}
_stamina.TakeStaminaDamage(uid, damage.StaminaCost, component, visual: false);
}
private void OnDamageExamine(EntityUid uid, DamageOtherOnHitComponent component, ref DamageExamineEvent args)
{
_damageExamine.AddDamageExamine(args.Message, GetDamage(uid, component, args.User), Loc.GetString("damage-throw"));
if (component.StaminaCost == 0)
return;
var staminaCostMarkup = FormattedMessage.FromMarkupOrThrow(
Loc.GetString("damage-stamina-cost",
("type", Loc.GetString("damage-throw")), ("cost", component.StaminaCost)));
args.Message.PushNewline();
args.Message.AddMessage(staminaCostMarkup);
}
}
}