Skip to content

Commit

Permalink
Защита от стамина урона + блокировка шприцов ухтантам и скафандрам (A…
Browse files Browse the repository at this point in the history
…dventureTimeSS14#314)

<!-- ЭТО ШАБЛОН ВАШЕГО PULL REQUEST. Текст между стрелками - это
комментарии - они не будут видны в PR. -->

## Описание PR
<!-- Ниже опишите ваш Pull Request. Что он изменяет? На что еще это
может повлиять? Постарайтесь описать все внесённые вами изменения! -->
Добавил защиту от стана и блокировку шприцов унатхам, а так же мобам в
скафандрах

**Медиа**
<!-- Если приемлемо, добавьте скриншоты для демонстрации вашего PR. Если
ваш PR представляет собой визуальное изменение, добавьте
скриншоты, иначе он может быть закрыт. -->

**Проверки**
<!-- Выполнение всех следующих действий, если это приемлемо для вида
изменений сильно ускорит разбор вашего PR -->
- [ ] PR полностью завершён и мне не нужна помощь чтобы его закончить.
- [ ] Я внимательно просмотрел все свои изменения и багов в них не
нашёл.
- [ ] Я запускал локальный сервер со своими изменениями и всё
протестировал.
- [ ] Я добавил скриншот/видео демонстрации PR в игре, **или** этот PR
этого не требует.

**Изменения**
<!--
Здесь вы можете написать список изменений, который будет автоматически
добавлен в игру, когда ваш PR будет принят.

В журнал изменений следует помещать только то, что действительно важно
игрокам.

В списке изменений тип значка не является часть предложения, поэтому
явно указывайте - Добавлен, Удалён, Изменён.
плохо: - add: Новый инструмент для инженеров
хорошо: - add: Добавлен новый инструмент для инженеров

Вы можете указать своё имя после символа 🆑 именно оно будет
отображаться в журнале изменений (иначе будет использоваться ваше имя на
GitHub)
Например: 🆑 Ian

-->

🆑 Котя
- add: Добавлена защита от стана скафандрам ЯО и СБ.
- add: Теперь шприцы не работают на мобов, которые носят скафандры.
- add: Шприцы так же перестали работать на унатхов даже без скафандра.

---------

Co-authored-by: bananchiki <[email protected]>
  • Loading branch information
FaDeOkno and Darkiich authored Aug 23, 2024
1 parent bf99abf commit d7bb906
Show file tree
Hide file tree
Showing 20 changed files with 206 additions and 5 deletions.
26 changes: 26 additions & 0 deletions Content.Server/ADT/Chemistry/Systems/InjectorsBlockerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Content.Shared.Chemistry;
using Content.Shared.Chemistry.Components;
using Content.Shared.Inventory;

namespace Content.Server.Chemistry.EntitySystems;

public sealed class InjectorsBlockerSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<InjectorsBlockerComponent, InjectAttemptEvent>(OnInjectAttempt);
SubscribeLocalEvent<InjectorsBlockerComponent, InventoryRelayedEvent<InjectAttemptEvent>>(OnInjectRelayAttempt);
}

private void OnInjectAttempt(EntityUid uid, InjectorsBlockerComponent comp, InjectAttemptEvent args)
{
args.Cancel();
}

private void OnInjectRelayAttempt(EntityUid uid, InjectorsBlockerComponent comp, InventoryRelayedEvent<InjectAttemptEvent> args)
{
args.Args.Cancel();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,9 @@ public abstract partial class BaseSolutionInjectOnEventComponent : Component
/// </summary>
[DataField]
public SlotFlags BlockSlots = SlotFlags.NONE;

// ADT Injector blocking start
[DataField]
public bool IgnoreBlockers = false;
// ADT Injector blocking end
}
10 changes: 10 additions & 0 deletions Content.Server/Chemistry/EntitySystems/HypospraySystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ public bool TryDoInject(Entity<HyposprayComponent> entity, EntityUid target, Ent
return false;
}

// ADT Injectors blocker start
if (!entity.Comp.IgnoreBlockers)
{
var blockerEv = new InjectAttemptEvent();
RaiseLocalEvent(target, blockerEv);
if (blockerEv.Cancelled)
return false;
}
// ADT Injectors blocker end

string? msgFormat = null;

if (target == user)
Expand Down
13 changes: 13 additions & 0 deletions Content.Server/Chemistry/EntitySystems/InjectorSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,19 @@ private void OnInjectorAfterInteract(Entity<InjectorComponent> entity, ref After
if (entity.Comp.IgnoreMobs)
return;

// ADT Injector blocking start
if (!entity.Comp.IgnoreBlockers)
{
var ev = new InjectAttemptEvent();
RaiseLocalEvent(target, ev);
if (ev.Cancelled)
{
Popup.PopupEntity(Loc.GetString("injector-component-fail-user", ("target", Identity.Entity(target, EntityManager))), target, args.User);
return;
}
}
// ADT Injector blocking end

InjectDoAfter(entity, target, args.User);
args.Handled = true;
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Content.Server.Body.Systems;
using Content.Server.Chemistry.Components;
using Content.Server.Chemistry.Containers.EntitySystems;
using Content.Shared.Chemistry;
using Content.Shared.Inventory;
using Content.Shared.Popups;
using Content.Shared.Projectiles;
Expand Down Expand Up @@ -33,11 +34,31 @@ public override void Initialize()

private void HandleProjectileHit(Entity<SolutionInjectOnProjectileHitComponent> entity, ref ProjectileHitEvent args)
{
// ADT Injector blocking start
if (!entity.Comp.IgnoreBlockers)
{
var ev = new InjectAttemptEvent();
RaiseLocalEvent(args.Target, ev);
if (ev.Cancelled)
return;
}
// ADT Injector blocking end

DoInjection((entity.Owner, entity.Comp), args.Target, args.Shooter);
}

private void HandleEmbed(Entity<SolutionInjectOnEmbedComponent> entity, ref EmbedEvent args)
{
// ADT Injector blocking start
if (!entity.Comp.IgnoreBlockers)
{
var ev = new InjectAttemptEvent();
RaiseLocalEvent(args.Embedded, ev);
if (ev.Cancelled)
return;
}
// ADT Injector blocking end

DoInjection((entity.Owner, entity.Comp), args.Embedded, args.Shooter);
}

Expand All @@ -46,7 +67,23 @@ private void HandleMeleeHit(Entity<MeleeChemicalInjectorComponent> entity, ref M
// MeleeHitEvent is weird, so we have to filter to make sure we actually
// hit something and aren't just examining the weapon.
if (args.IsHit)
TryInjectTargets((entity.Owner, entity.Comp), args.HitEntities, args.User);
{
List<EntityUid> list = new();
foreach (var ent in args.HitEntities)
{
// ADT Injector blocking start
if (!entity.Comp.IgnoreBlockers)
{
var ev = new InjectAttemptEvent();
RaiseLocalEvent(ent, ev);
if (ev.Cancelled)
continue;
list.Add(ent);
}
// ADT Injector blocking end
}
TryInjectTargets((entity.Owner, entity.Comp), list, args.User);
}
}

private void DoInjection(Entity<BaseSolutionInjectOnEventComponent> injectorEntity, EntityUid target, EntityUid? source = null)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.DoAfter;
using Content.Shared.FixedPoint;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;

namespace Content.Shared.Chemistry.Components;

[RegisterComponent, NetworkedComponent]
public sealed partial class InjectorsBlockerComponent : Component
{
}
13 changes: 13 additions & 0 deletions Content.Shared/ADT/Chemistry/Events/InjectAttemptEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Content.Shared.Inventory;

namespace Content.Shared.Chemistry;

public sealed class InjectAttemptEvent : CancellableEntityEventArgs, IInventoryRelayEvent
{
// Whenever locational damage is a thing, this should just check only that bit of armour.
public SlotFlags TargetSlots { get; } = ~SlotFlags.POCKET;

public InjectAttemptEvent()
{
}
}
8 changes: 8 additions & 0 deletions Content.Shared/Armor/ArmorComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ public sealed partial class ArmorComponent : Component
/// </summary>
[DataField]
public float PriceMultiplier = 1;

// ADT Stunmeta fix start
/// <summary>
/// Stamina damage reduction
/// </summary>
[DataField]
public float StaminaModifier = 1f;
// ADT Stunmeta fix
}

/// <summary>
Expand Down
18 changes: 16 additions & 2 deletions Content.Shared/Armor/SharedArmorSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Examine;
using Content.Shared.Inventory;
using Content.Shared.Silicons.Borgs;
Expand All @@ -22,6 +23,7 @@ public override void Initialize()
SubscribeLocalEvent<ArmorComponent, InventoryRelayedEvent<DamageModifyEvent>>(OnDamageModify);
SubscribeLocalEvent<ArmorComponent, BorgModuleRelayedEvent<DamageModifyEvent>>(OnBorgDamageModify);
SubscribeLocalEvent<ArmorComponent, GetVerbsEvent<ExamineVerb>>(OnArmorVerbExamine);
SubscribeLocalEvent<ArmorComponent, InventoryRelayedEvent<StaminaDamageModifyEvent>>(OnStaminaDamageModify); // ADT Stunmeta fix
}

private void OnDamageModify(EntityUid uid, ArmorComponent component, InventoryRelayedEvent<DamageModifyEvent> args)
Expand All @@ -40,7 +42,7 @@ private void OnArmorVerbExamine(EntityUid uid, ArmorComponent component, GetVerb
if (!args.CanInteract || !args.CanAccess)
return;

var examineMarkup = GetArmorExamine(component.Modifiers);
var examineMarkup = GetArmorExamine(component.Modifiers, component.StaminaModifier); // ADT Stunmeta fix

var ev = new ArmorExamineEvent(examineMarkup);
RaiseLocalEvent(uid, ref ev);
Expand All @@ -50,7 +52,7 @@ private void OnArmorVerbExamine(EntityUid uid, ArmorComponent component, GetVerb
Loc.GetString("armor-examinable-verb-message"));
}

private FormattedMessage GetArmorExamine(DamageModifierSet armorModifiers)
private FormattedMessage GetArmorExamine(DamageModifierSet armorModifiers, float staminaModifier) // ADT Stunmeta fix
{
var msg = new FormattedMessage();
msg.AddMarkupOrThrow(Loc.GetString("armor-examine"));
Expand All @@ -77,6 +79,18 @@ private FormattedMessage GetArmorExamine(DamageModifierSet armorModifiers)
));
}

// ADT Stunmeta fix start
msg.PushNewline();
msg.AddMarkup(Loc.GetString("armor-stamina-protection-value", ("value", MathF.Round((1f - staminaModifier) * 100, 1))));
// ADT Stunmeta fix end

return msg;
}

// ADT Stunmeta fix start
private void OnStaminaDamageModify(EntityUid uid, ArmorComponent component, InventoryRelayedEvent<StaminaDamageModifyEvent> args)
{
args.Args.Damage *= component.StaminaModifier;
}
// ADT Stunmeta fix end
}
6 changes: 6 additions & 0 deletions Content.Shared/Chemistry/Components/HyposprayComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,10 @@ public sealed partial class HyposprayComponent : Component
/// </summary>
[DataField]
public bool InjectOnly = false;

// ADT Injector blocking start
[DataField]
public bool IgnoreBlockers = true; // Мало ли будете вводить гипоспреи обычным врачам. Таким подобной роскоши не нужно
// ADT Injector blocking end

}
6 changes: 6 additions & 0 deletions Content.Shared/Chemistry/Components/InjectorComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ public sealed partial class InjectorComponent : Component
public float MovementThreshold = 0.1f;

#endregion


// ADT Injector blocking start
[DataField]
public bool IgnoreBlockers = false;
// ADT Injector blocking end
}

/// <summary>
Expand Down
34 changes: 32 additions & 2 deletions Content.Shared/Damage/Systems/StaminaSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Content.Shared.Database;
using Content.Shared.Effects;
using Content.Shared.IdentityManagement;
using Content.Shared.Inventory;
using Content.Shared.Popups;
using Content.Shared.Projectiles;
using Content.Shared.Rejuvenate;
Expand Down Expand Up @@ -233,7 +234,8 @@ public bool TryTakeStamina(EntityUid uid, float value, StaminaComponent? compone
}

public void TakeStaminaDamage(EntityUid uid, float value, StaminaComponent? component = null,
EntityUid? source = null, EntityUid? with = null, bool visual = true, SoundSpecifier? sound = null)
EntityUid? source = null, EntityUid? with = null, bool visual = true, SoundSpecifier? sound = null,
bool ignoreResistances = false) // ADT Stunmeta fix
{
if (!Resolve(uid, ref component, false))
return;
Expand All @@ -247,6 +249,15 @@ public void TakeStaminaDamage(EntityUid uid, float value, StaminaComponent? comp
if (component.Critical)
return;

// ADT Stunmeta fix start
if (!ignoreResistances)
{
var modifyEv = new StaminaDamageModifyEvent(value, source);
RaiseLocalEvent(uid, modifyEv);
value = modifyEv.Damage;
}
// ADT Stunmeta fix end

var oldDamage = component.StaminaDamage;
component.StaminaDamage = MathF.Max(0f, component.StaminaDamage + value);

Expand Down Expand Up @@ -392,7 +403,26 @@ private void ExitStamCrit(EntityUid uid, StaminaComponent? component = null)
}

/// <summary>
/// Raised before stamina damage is dealt to allow other systems to cancel it.
/// Raised before stamina damage is dealt to allow other systems to modify it.
/// </summary>
[ByRefEvent]
public record struct BeforeStaminaDamageEvent(float Value, bool Cancelled = false);

// ADT Stunmeta fix start
public sealed class StaminaDamageModifyEvent : EntityEventArgs, IInventoryRelayEvent
{
// Whenever locational damage is a thing, this should just check only that bit of armour.
public SlotFlags TargetSlots { get; } = ~SlotFlags.POCKET;

public readonly float OriginalDamage;
public float Damage;
public EntityUid? Origin;

public StaminaDamageModifyEvent(float damage, EntityUid? origin = null)
{
OriginalDamage = damage;
Damage = damage;
Origin = origin;
}
}
// ADT Stunmeta fix end
3 changes: 3 additions & 0 deletions Content.Shared/Inventory/InventorySystem.Relay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Content.Shared.Temperature;
using Content.Shared.Verbs;
using Content.Shared.ADT.Phantom.Components;
using Content.Shared.Damage.Systems;

namespace Content.Shared.Inventory;

Expand All @@ -31,6 +32,8 @@ public void InitializeRelay()
SubscribeLocalEvent<InventoryComponent, ModifyChangedTemperatureEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, GetDefaultRadioChannelEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, RefreshNameModifiersEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, StaminaDamageModifyEvent>(RelayInventoryEvent); // ADT Stunmeta fix
SubscribeLocalEvent<InventoryComponent, InjectAttemptEvent>(RelayInventoryEvent); // ADT Injector blocking

// by-ref events
SubscribeLocalEvent<InventoryComponent, GetExplosionResistanceEvent>(RefRelayInventoryEvent);
Expand Down
1 change: 1 addition & 0 deletions Resources/Locale/ru-RU/ADT/armor/armor-examine.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
armor-stamina-protection-value = - [color=cyan] Стамина [/color] урон снижается на [color=lightblue]{ $value }%[/color].
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
injector-component-fail-user = Вы не можете ввести содержимое шприца в { CAPITALIZE($target) }.
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@
- type: BatterySelfRecharger
autoRecharge: true
autoRechargeRate: 2
- type: InjectorsBlocker # ADT

- type: entity
parent: ClothingOuterBaseLarge
Expand Down Expand Up @@ -212,6 +213,7 @@
- type: GroupExamine
- type: ClothingRequiredStepTriggerImmune
slots: WITHOUT_POCKET
- type: InjectorsBlocker # ADT

- type: entity
parent: ClothingOuterArmorHeavy
Expand Down Expand Up @@ -310,6 +312,7 @@
- type: GroupExamine
- type: ClothingRequiredStepTriggerImmune
slots: WITHOUT_POCKET
- type: InjectorsBlocker # ADT

- type: entity
parent: ClothingOuterBaseLarge
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,16 @@
- WhitelistChameleon
- type: ClothingRequiredStepTriggerImmune
slots: WITHOUT_POCKET

- type: InjectorsBlocker

- type: DamageOnInteractProtection
damageProtection:
flatReductions:
Heat: 10 # the average lightbulb only does around four damage!
slots: OUTERCLOTHING


- type: entity
abstract: true
parent: [ClothingOuterBase, AllowSuitStorageClothing]
Expand Down
Loading

0 comments on commit d7bb906

Please sign in to comment.