Skip to content

Commit

Permalink
Melee rework 1/4: combo system (#1108)
Browse files Browse the repository at this point in the history
## Описание PR
<!-- Что вы изменили в этом пулл реквесте? -->
добавила систему комбо ударов, дальше читать чейнджлог

## Почему / Баланс
<!-- Почему оно было изменено? Ссылайтесь на любые обсуждения или
вопросы здесь. Пожалуйста, обсудите, как это повлияет на игровой баланс.
-->

1. было в сс13
2. робаст
3. текущие ближние бои скучны

## Техническая информация
<!-- Если речь идет об изменении кода, кратко изложите на высоком уровне
принцип работы нового кода. Это облегчает рецензирование.- -->
все comboEffects в компоненте потому, что там удобнее
так же в методе для кнокдауна 2 новых поля down(упадёт ли человек после
стана) и dropitems, что отвечает за выпадение вещей из рук после падения

 
## Медиа
<!--
Пулл реквесты, которые вносят внутриигровые изменения (добавление
одежды, предметов, новых возможностей и т.д.), должны содержать медиа,
демонстрирующие изменения.
Небольшие исправления/рефакторы не требуют медиа.

Если Вы не уверены в том, что Ваш пулл реквест требует медиа, спросите
мейнтейнера.
-->
я бы показала, но весит слишком много

## Требования
<!--
В связи с наплывом ПР'ов нам необходимо убедиться, что ПР'ы следуют
правильным рекомендациям.

Пожалуйста, уделите время прочтению, если делаете пулл реквест (ПР)
впервые.

Отметьте поля ниже, чтобы подтвердить, что Вы действительно видели их
(поставьте X в скобках, например [X]):
-->
- [x] Я прочитал(а) и следую [Руководство по созданию пулл
реквестов](https://docs.spacestation14.com/en/general-development/codebase-info/pull-request-guidelines.html).
Я понимаю, что в противном случае мой ПР может быть закрыт по усмотрению
мейнтейнера.
- [x] Я добавил скриншоты/видео к этому пулл реквесту, демонстрирующие
его изменения в игре, **или** этот пулл реквест не требует демонстрации
в игре

## Критические изменения
<!--
Перечислите все критические изменения, включая изменения пространства
имён, публичных классов/методов/полей, переименования прототипов, и
предоставьте инструкции по их исправлению.
-->

**Чейнджлог**

🆑 Ratyyy & Котя & Тамиоки

- add: НТ начали поставлять повару и осщ книгу "cqc для самых
маленьких", прочитав которую можно научиться использовать cqc - стиль
боя со своими комбинациями атак!
- add: НТ начали поставлять во все шкафчики офицеров книгу "как получить
ПТСР", что обучает соответствующему стилю боя!
- add: Синдикат, не отставая от НТ, выдал своим агентам стиль спящего
карпа и cqc в список возможного оружия!
 - add: Экипаж станции научился прыгать в своих врагов с двух ног!
- add: По результату собрания из одного умного человека, был улучшен
револьвер ОСЩ,, благодаря чему он стал стрелять быстрее и заряжаться за
куда меньшее время!
  • Loading branch information
Ratyyy authored Feb 18, 2025
1 parent baf8114 commit c20b1a1
Show file tree
Hide file tree
Showing 39 changed files with 935 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Robust.Shared.Prototypes;

namespace Content.Server.ADT.AddComponentsOnUse;

[RegisterComponent]
public sealed partial class AddComponentsOnUseComponent : Component
{
/// <summary>
/// The components to add when activated.
/// </summary>
[DataField(required: true)]
public ComponentRegistry Components = new();

[DataField]
public bool DeleteOnUse = true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Content.Shared.Interaction.Events;

namespace Content.Server.ADT.AddComponentsOnUse;

public sealed class AddComponentsOnUseSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AddComponentsOnUseComponent, UseInHandEvent>(OnUsed);
}

private void OnUsed(EntityUid uid, AddComponentsOnUseComponent component, UseInHandEvent args)
{
EntityManager.AddComponents(args.User, component.Components);
if (component.DeleteOnUse)
QueueDel(uid);
}
}
7 changes: 7 additions & 0 deletions Content.Server/ADT/Combat/Systems/ComboSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Content.Shared.ADT.Combat;

namespace Content.Server.ADT.Combat;

public sealed partial class ComboSystem : SharedComboSystem
{
}
3 changes: 2 additions & 1 deletion Content.Server/Hands/Systems/HandsSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ private void OnDisarmed(EntityUid uid, HandsComponent component, DisarmedEvent a
{
if (args.Handled)
return;

if (args.Source == uid) ///ADT tweak
return;
// Break any pulls
if (TryComp(uid, out PullerComponent? puller) && TryComp(puller.Pulling, out PullableComponent? pullable))
_pullingSystem.TryStopPull(puller.Pulling.Value, pullable);
Expand Down
3 changes: 2 additions & 1 deletion Content.Server/Weapons/Melee/MeleeWeaponSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ protected override bool DoDisarm(EntityUid user, DisarmAttackEvent ev, EntityUid
{
RaiseLocalEvent(inTargetHand.Value, attemptEvent);
}

RaiseLocalEvent(user, attemptEvent); //ADT tweak
RaiseLocalEvent(target, attemptEvent);

if (attemptEvent.Cancelled)
Expand All @@ -155,6 +155,7 @@ protected override bool DoDisarm(EntityUid user, DisarmAttackEvent ev, EntityUid

var eventArgs = new DisarmedEvent { Target = target, Source = user, PushProbability = 0.22f }; // ADT Disarm tweak
RaiseLocalEvent(target, eventArgs);
RaiseLocalEvent(user, eventArgs); //ADT tweak

if (!eventArgs.Handled)
{
Expand Down
19 changes: 19 additions & 0 deletions Content.Shared/ADT/CantShoot/Components/CantShootComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Content.Shared.Whitelist;
using Robust.Shared.Audio;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Shared.ADT.CantShoot;

[RegisterComponent]
public sealed partial class CantShootComponent : Component
{
[DataField]
public string? Popup;

[DataField]
public EntityWhitelist? Whitelist;
}
25 changes: 25 additions & 0 deletions Content.Shared/ADT/CantShoot/Systems/CantShootSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Content.Shared.Weapons.Ranged.Events;
using Content.Shared.Popups;
using Content.Shared.Whitelist;

namespace Content.Shared.ADT.CantShoot;

public sealed class CantShootSystem : EntitySystem
{
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CantShootComponent, ShotAttemptedEvent>(OnShootAttempt);
}

private void OnShootAttempt(EntityUid uid, CantShootComponent component, ref ShotAttemptedEvent args)
{
if (_whitelist.IsWhitelistPassOrNull(component.Whitelist, args.Used))
return;
if (component.Popup != null)
_popup.PopupCursor(Loc.GetString(component.Popup, ("used", args.Used)), args.User);
args.Cancel();
}
}
24 changes: 24 additions & 0 deletions Content.Shared/ADT/Combat/ComboComponentParts.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Robust.Shared.Serialization;

namespace Content.Shared.ADT.Combat;

[Serializable, NetSerializable]
public enum CombatAction
{
Disarm,
Grab,
Hit
}

[DataDefinition]
public sealed partial class CombatMove
{
/// <summary>
/// это надо указывать в прототипе в виде списка
/// </summary>
[DataField]
public List<CombatAction> ActionsNeeds { get; private set; } = new List<CombatAction>();

[DataField]
public List<IComboEffect> ComboEvent = new List<IComboEffect>{};
}
164 changes: 164 additions & 0 deletions Content.Shared/ADT/Combat/ComboEffects.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
using Robust.Shared.Serialization;
using Content.Shared.Damage;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Popups;
using Content.Shared.Damage.Systems;
using Content.Shared.Standing;
using Content.Shared.Stunnable;
using Content.Shared.ADT.Crawling;
using Content.Shared.IdentityManagement;
using Content.Shared.Coordinates;
using Content.Shared.Hands.Components;
using Content.Shared.StatusEffect;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;

namespace Content.Shared.ADT.Combat;

[ImplicitDataDefinitionForInheritors]
public partial interface IComboEffect
{
void DoEffect(EntityUid user, EntityUid target, IEntityManager entMan);
}

[Serializable, NetSerializable]
public sealed partial class ComboDamageEffect : IComboEffect
{
[DataField]
public DamageSpecifier Damage;

public void DoEffect(EntityUid user, EntityUid target, IEntityManager entMan)
{
var damageable = entMan.System<DamageableSystem>();
damageable.TryChangeDamage(target, Damage);
}
}
[Serializable, NetSerializable]
public sealed partial class ComboStaminaDamageEffect : IComboEffect
{
[DataField]
public int StaminaDamage;

public void DoEffect(EntityUid user, EntityUid target, IEntityManager entMan)
{
var stun = entMan.System<StaminaSystem>();
stun.TakeStaminaDamage(target, StaminaDamage);
}
}
[Serializable, NetSerializable]
public sealed partial class ComboSpawnEffect : IComboEffect
{
[DataField]
public string? SpawnOnUser;
[DataField]
public string? SpawnOnTarget;

public void DoEffect(EntityUid user, EntityUid target, IEntityManager entMan)
{
if (SpawnOnTarget != null)
entMan.SpawnAtPosition(SpawnOnTarget, target.ToCoordinates());
if (SpawnOnUser != null)
entMan.SpawnAtPosition(SpawnOnUser, target.ToCoordinates());
}
}
[Serializable, NetSerializable]
public sealed partial class ComboFallEffect : IComboEffect
{
[DataField]
public bool DropItems;

public void DoEffect(EntityUid user, EntityUid target, IEntityManager entMan)
{
if (!entMan.HasComponent<CrawlerComponent>(target))
return;
var down = entMan.System<StandingStateSystem>();
down.Down(target, dropHeldItems: DropItems);
}
}

[Serializable, NetSerializable]
public sealed partial class ComboMoreDamageToDownedEffect : IComboEffect
{
[DataField(required: true)]
public DamageSpecifier Damage;
[DataField]
public bool IgnoreResistances;
public void DoEffect(EntityUid user, EntityUid target, IEntityManager entMan)
{
var down = entMan.System<StandingStateSystem>();
var damageable = entMan.System<DamageableSystem>();
if (down.IsDown(target))
{
damageable.TryChangeDamage(target, Damage, IgnoreResistances);
}
}
}
[Serializable, NetSerializable]
public sealed partial class ComboStunEffect : IComboEffect
{
[DataField]
public bool Fall = true;
[DataField]
public int StunTime;
[DataField]
public bool DropItems = true;

public void DoEffect(EntityUid user, EntityUid target, IEntityManager entMan)
{
if (!entMan.TryGetComponent<StatusEffectsComponent>(target, out var status))
return;
var down = entMan.System<SharedStunSystem>();
down.TryParalyze(target, TimeSpan.FromSeconds(StunTime), false, status, dropItems: DropItems, down: Fall);
}
}
[Serializable, NetSerializable]
public sealed partial class ComboDropFromActiveHandEffect : IComboEffect
{
[DataField]
public bool Fall = true;
[DataField]
public TimeSpan StunTime;
[DataField]
public bool DropItems = true;

public void DoEffect(EntityUid user, EntityUid target, IEntityManager entMan)
{
var down = entMan.System<SharedStunSystem>();
down.TryKnockdown(target, StunTime, true, dropItems: DropItems, down: Fall);
}
}
[Serializable, NetSerializable]
public sealed partial class ComboPopupEffect : IComboEffect
{
[DataField]
public string LocaleText;

public void DoEffect(EntityUid user, EntityUid target, IEntityManager entMan)
{
var popup = entMan.System<SharedPopupSystem>();
popup.PopupEntity(Loc.GetString(LocaleText, ("user", Identity.Entity(user, entMan)), ("target", target)), target, PopupType.LargeCaution);
}
}
[Serializable, NetSerializable]
public sealed partial class ComboDropFromHandsEffect : IComboEffect
{
public void DoEffect(EntityUid user, EntityUid target, IEntityManager entMan)
{
var hands = entMan.System<SharedHandsSystem>();
if (!entMan.TryGetComponent<HandsComponent>(target, out var hand) || hand.ActiveHand == null)
return;
hands.DoDrop(target, hand.ActiveHand);
}
}
[Serializable, NetSerializable]
public sealed partial class ComboAudioEffect : IComboEffect
{
[DataField]
public SoundSpecifier? Sound;

public void DoEffect(EntityUid user, EntityUid target, IEntityManager entMan)
{
var audio = entMan.System<SharedAudioSystem>();
audio.PlayPvs(Sound, user);
}
}
12 changes: 12 additions & 0 deletions Content.Shared/ADT/Combat/Components/ComboComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Robust.Shared.GameStates;

namespace Content.Shared.ADT.Combat;

[RegisterComponent, NetworkedComponent]
public sealed partial class ComboComponent : Component
{
[DataField]
public List<CombatMove> AvailableMoves { get; private set; } = new List<CombatMove>();
public EntityUid TargetEntity;
public List<CombatAction> CurrestActions { get; private set; } = new List<CombatAction>();
}
Loading

0 comments on commit c20b1a1

Please sign in to comment.