Fixes & more (#548)

* - fix: Narsie not spawning, items not dropping on paralyze, cult tweaks.

* - fix: Diagonal grilles layer.

* - add: Cockroaches don't drop organs.

* - add: Magic hands now work on interact & disable context menu interaction.

* - fix: Shackles speech after doafter.

* - tweak: Reduce flashbang knockdown, check for CanLieDown.

* - tweak: Hspear limit.

* - tweak: Remove knockdown tile friction.

* - tweak: Engi belt in sus box.

* - fix: Constructs can hear cult chat.

* - fix: Desword audio.

* - fix: Context menu.

* - fix: Actually drop items on paralyze.

* - tweak: Revert range reduction.

* - add: Update thermal visibility.

* - add: NPCs can miss.

* - tweak: Update desc.

* - fix: Actually fix desword audio.

* - tweak: Secret weights & game presets.

* - fix: Cult stun.
This commit is contained in:
Aviu00
2024-08-03 15:23:46 +00:00
committed by GitHub
parent 7f7cb34c0c
commit d4525a91e6
33 changed files with 152 additions and 125 deletions

View File

@@ -3,12 +3,15 @@ using System.Numerics;
using Content.Client.CombatMode; using Content.Client.CombatMode;
using Content.Client.Examine; using Content.Client.Examine;
using Content.Client.Gameplay; using Content.Client.Gameplay;
using Content.Client.Popups;
using Content.Client.Verbs; using Content.Client.Verbs;
using Content.Client.Verbs.UI; using Content.Client.Verbs.UI;
using Content.Shared.CCVar; using Content.Shared.CCVar;
using Content.Shared.Examine; using Content.Shared.Examine;
using Content.Shared.IdentityManagement; using Content.Shared.IdentityManagement;
using Content.Shared.Input; using Content.Shared.Input;
using Content.Shared.Mobs.Components;
using Content.Shared.Popups;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Client.Input; using Robust.Client.Input;
@@ -50,6 +53,7 @@ namespace Content.Client.ContextMenu.UI
[UISystemDependency] private readonly ExamineSystem _examineSystem = default!; [UISystemDependency] private readonly ExamineSystem _examineSystem = default!;
[UISystemDependency] private readonly TransformSystem _xform = default!; [UISystemDependency] private readonly TransformSystem _xform = default!;
[UISystemDependency] private readonly CombatModeSystem _combatMode = default!; [UISystemDependency] private readonly CombatModeSystem _combatMode = default!;
[UISystemDependency] private readonly PopupSystem _popup = default!; // WD EDIT
private bool _updating; private bool _updating;
@@ -124,6 +128,19 @@ namespace Content.Client.ContextMenu.UI
return; return;
} }
// WD START
var localEntity = _playerManager.LocalEntity;
if (args.Function == EngineKeyFunctions.Use &&
EntityManager.HasComponent<MobStateComponent>(entity.Value) && entity.Value != localEntity)
{
_popup.PopupClient(Loc.GetString("context-menu-cant-interact"),
entity.Value, localEntity, PopupType.MediumCaution);
_context.Close();
args.Handle();
return;
}
// WD END
// do some other server-side interaction? // do some other server-side interaction?
if (args.Function == EngineKeyFunctions.Use || if (args.Function == EngineKeyFunctions.Use ||
args.Function == ContentKeyFunctions.ActivateItemInWorld || args.Function == ContentKeyFunctions.ActivateItemInWorld ||

View File

@@ -1,7 +1,9 @@
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Content.Client.Stealth;
using Content.Shared._White.Overlays; using Content.Shared._White.Overlays;
using Content.Shared.Body.Components; using Content.Shared.Body.Components;
using Content.Shared.Stealth.Components;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Client.Player; using Robust.Client.Player;
@@ -19,6 +21,7 @@ public sealed class ThermalVisionOverlay : Overlay
private readonly TransformSystem _transform; private readonly TransformSystem _transform;
private readonly OccluderSystem _occluder; private readonly OccluderSystem _occluder;
private readonly PointLightSystem _pointLight; private readonly PointLightSystem _pointLight;
private readonly StealthSystem _stealth;
public override OverlaySpace Space => OverlaySpace.WorldSpace; public override OverlaySpace Space => OverlaySpace.WorldSpace;
@@ -33,6 +36,7 @@ public sealed class ThermalVisionOverlay : Overlay
_transform = _entity.System<TransformSystem>(); _transform = _entity.System<TransformSystem>();
_occluder = _entity.System<OccluderSystem>(); _occluder = _entity.System<OccluderSystem>();
_pointLight = _entity.System<PointLightSystem>(); _pointLight = _entity.System<PointLightSystem>();
_stealth = _entity.System<StealthSystem>();
ZIndex = -1; ZIndex = -1;
} }
@@ -125,7 +129,9 @@ public sealed class ThermalVisionOverlay : Overlay
private bool CanSee(EntityUid ent, SpriteComponent sprite) private bool CanSee(EntityUid ent, SpriteComponent sprite)
{ {
return sprite.Visible && !_entity.HasComponent<ThermalBlockerComponent>(ent); return sprite.Visible && !_entity.HasComponent<ThermalBlockerComponent>(ent) &&
(!_entity.TryGetComponent(ent, out StealthComponent? stealth) ||
_stealth.GetVisibility(ent, stealth) > 0.5f);
} }
private bool HasOccluders(EntityUid ent) private bool HasOccluders(EntityUid ent)

View File

@@ -24,6 +24,7 @@ using Content.Shared.Mobs.Systems;
using Content.Shared.Players; using Content.Shared.Players;
using Content.Shared.Radio; using Content.Shared.Radio;
using Content.Shared._White; using Content.Shared._White;
using Content.Shared._White.Cult.Components;
using Content.Shared.Speech; using Content.Shared.Speech;
using Content.Shared._White.Cult.Systems; using Content.Shared._White.Cult.Systems;
using Robust.Server.Player; using Robust.Server.Player;
@@ -795,6 +796,7 @@ public sealed partial class ChatSystem : SharedChatSystem
return Filter.Empty() return Filter.Empty()
.AddWhereAttachedEntity(HasComp<GhostComponent>) .AddWhereAttachedEntity(HasComp<GhostComponent>)
.AddWhereAttachedEntity(HasComp<CultistComponent>) .AddWhereAttachedEntity(HasComp<CultistComponent>)
.AddWhereAttachedEntity(HasComp<ConstructComponent>)
.Recipients .Recipients
.Union(_adminManager.ActiveAdmins) .Union(_adminManager.ActiveAdmins)
.Select(p => p.Channel); .Select(p => p.Channel);

View File

@@ -14,7 +14,7 @@ public sealed partial class CultRitesHandComponent : BaseMagicHandComponent
public SoundSpecifier SuckSound = new SoundPathSpecifier("/Audio/White/Cult/enter_blood.ogg"); public SoundSpecifier SuckSound = new SoundPathSpecifier("/Audio/White/Cult/enter_blood.ogg");
[DataField] [DataField]
public float HealModifier = 0.5f; public float HealModifier = 1f;
[DataField(customTypeSerializer: typeof(PrototypeIdListSerializer<CultistFactoryProductionPrototype>))] [DataField(customTypeSerializer: typeof(PrototypeIdListSerializer<CultistFactoryProductionPrototype>))]
public List<string> BloodRites = new () public List<string> BloodRites = new ()

View File

@@ -17,11 +17,11 @@ using Content.Shared.Examine;
using Content.Shared.FixedPoint; using Content.Shared.FixedPoint;
using Content.Shared.Fluids.Components; using Content.Shared.Fluids.Components;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems; using Content.Shared.Mobs.Systems;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.StatusEffect; using Content.Shared.StatusEffect;
using Content.Shared.UserInterface; using Content.Shared.UserInterface;
using Content.Shared.Weapons.Melee.Events;
using Robust.Server.Audio; using Robust.Server.Audio;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -50,9 +50,8 @@ public sealed class MagicHandSystem : EntitySystem
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<CultStunHandComponent, MeleeHitEvent>(OnStunHit); SubscribeLocalEvent<CultStunHandComponent, AfterInteractEvent>(OnStunInteract);
SubscribeLocalEvent<CultRitesHandComponent, MeleeHitEvent>(OnRitesHit); SubscribeLocalEvent<CultRitesHandComponent, AfterInteractEvent>(OnRitesInteract);
SubscribeLocalEvent<CultRitesHandComponent, AfterInteractEvent>(OnInteract);
SubscribeLocalEvent<CultRitesHandComponent, CultistFactoryItemSelectedMessage>(OnBloodRitesSelected); SubscribeLocalEvent<CultRitesHandComponent, CultistFactoryItemSelectedMessage>(OnBloodRitesSelected);
SubscribeLocalEvent<CultRitesHandComponent, ActivatableUIOpenAttemptEvent>(OnRitesSelectAttempt); SubscribeLocalEvent<CultRitesHandComponent, ActivatableUIOpenAttemptEvent>(OnRitesSelectAttempt);
SubscribeLocalEvent<CultRitesHandComponent, BeforeActivatableUIOpenEvent>(BeforeRitesSelect); SubscribeLocalEvent<CultRitesHandComponent, BeforeActivatableUIOpenEvent>(BeforeRitesSelect);
@@ -122,17 +121,26 @@ public sealed class MagicHandSystem : EntitySystem
cultist.RitesBloodAmount -= prototype.BloodCost; cultist.RitesBloodAmount -= prototype.BloodCost;
} }
private void OnInteract(Entity<CultRitesHandComponent> ent, ref AfterInteractEvent args) private void OnRitesInteract(Entity<CultRitesHandComponent> ent, ref AfterInteractEvent args)
{ {
if (!args.CanReach || args.Target is not { } target) if (!args.CanReach || args.Target is not { } target)
return; return;
if (!TryComp(args.User, out CultistComponent? cultist))
return;
if (HasComp<CultistComponent>(target) || HasComp<ConstructComponent>(target))
{
RitesHeal(ent, target, args.User, cultist);
return;
}
var puddleQuery = GetEntityQuery<PuddleComponent>(); var puddleQuery = GetEntityQuery<PuddleComponent>();
if (!puddleQuery.HasComp(target)) if (!puddleQuery.HasComp(target))
return; return;
if (!TryComp(args.User, out BloodstreamComponent? bloodstreamComponent) || if (!TryComp(args.User, out BloodstreamComponent? bloodstreamComponent))
!TryComp(args.User, out CultistComponent? cultist))
return; return;
var xform = Transform(target); var xform = Transform(target);
@@ -176,28 +184,22 @@ public sealed class MagicHandSystem : EntitySystem
args.Handled = true; args.Handled = true;
} }
private void OnRitesHit(Entity<CultRitesHandComponent> ent, ref MeleeHitEvent args) private void RitesHeal(Entity<CultRitesHandComponent> ent, EntityUid target, EntityUid user, CultistComponent cultist)
{ {
if (args.HitEntities.Count == 0)
return;
var target = args.HitEntities[0];
var (uid, comp) = ent; var (uid, comp) = ent;
QueueDel(uid); if (!TryComp(target, out DamageableComponent? damageable) || !TryComp(target, out MobStateComponent? mobState))
if (!TryComp(args.User, out CultistComponent? cultist) || !TryComp(target, out DamageableComponent? damageable))
return; return;
if (_mobState.IsDead(target)) if (_mobState.IsDead(target, mobState))
{ {
Popup(Loc.GetString("cult-rites-dead"), args.User); Popup(Loc.GetString("cult-rites-dead"), user);
return; return;
} }
if (cultist.RitesBloodAmount <= FixedPoint2.Zero) if (cultist.RitesBloodAmount <= FixedPoint2.Zero)
{ {
Popup(Loc.GetString("cult-rites-heal-no-blood"), args.User); Popup(Loc.GetString("cult-rites-heal-no-blood"), user);
return; return;
} }
@@ -205,27 +207,32 @@ public sealed class MagicHandSystem : EntitySystem
var totalDamage = damage.GetTotal(); var totalDamage = damage.GetTotal();
if (totalDamage <= FixedPoint2.Zero) if (totalDamage <= FixedPoint2.Zero)
{ {
Popup(Loc.GetString("cult-rites-already-healed"), args.User); Popup(Loc.GetString("cult-rites-already-healed"), user);
return; return;
} }
QueueDel(uid);
var coef = FixedPoint2.Min(cultist.RitesBloodAmount * comp.HealModifier, totalDamage) / totalDamage; var coef = FixedPoint2.Min(cultist.RitesBloodAmount * comp.HealModifier, totalDamage) / totalDamage;
cultist.RitesBloodAmount = cultist.RitesBloodAmount =
FixedPoint2.Max(FixedPoint2.Zero, cultist.RitesBloodAmount - totalDamage / comp.HealModifier); FixedPoint2.Max(FixedPoint2.Zero, cultist.RitesBloodAmount - totalDamage / comp.HealModifier);
_damageable.TryChangeDamage(target, -damage * coef, true, false, damageable, args.User); _damageable.TryChangeDamage(target, -damage * coef, true, false, damageable, user);
Popup(Loc.GetString("cult-rites-after-heal", ("blood", cultist.RitesBloodAmount)), args.User); Popup(Loc.GetString("cult-rites-after-heal", ("blood", cultist.RitesBloodAmount)), user);
_audio.PlayPvs(comp.HealSound, target); _audio.PlayPvs(comp.HealSound, target);
Speak(args.User, comp); Speak(user, comp);
} }
private void OnStunHit(Entity<CultStunHandComponent> ent, ref MeleeHitEvent args) private void OnStunInteract(Entity<CultStunHandComponent> ent, ref AfterInteractEvent args)
{ {
if (args.HitEntities.Count == 0) if (!args.CanReach || args.Target is not { } target)
return; return;
var target = args.HitEntities[0];
var (uid, comp) = ent; var (uid, comp) = ent;
if (uid == target || !TryComp(target, out StatusEffectsComponent? status) ||
HasComp<CultistComponent>(target) || HasComp<ConstructComponent>(target))
return;
QueueDel(uid); QueueDel(uid);
Spawn("CultStunFlashEffect", Transform(target).Coordinates); Spawn("CultStunFlashEffect", Transform(target).Coordinates);
Speak(args.User, comp); Speak(args.User, comp);
@@ -241,8 +248,8 @@ public sealed class MagicHandSystem : EntitySystem
var halo = HasComp<PentagramComponent>(args.User); var halo = HasComp<PentagramComponent>(args.User);
_statusEffects.TryAddStatusEffect(target, "Muted", halo ? comp.HaloMuteDuration : comp.MuteDuration, true, _statusEffects.TryAddStatusEffect(target, "Muted", halo ? comp.HaloMuteDuration : comp.MuteDuration, true,
"Muted"); "Muted", status);
_stun.TryParalyze(target, halo ? comp.HaloDuration : comp.Duration, true); _stun.TryParalyze(target, halo ? comp.HaloDuration : comp.Duration, true, status);
} }
private void Popup(string msg, EntityUid user, PopupType type = PopupType.Small) private void Popup(string msg, EntityUid user, PopupType type = PopupType.Small)

View File

@@ -0,0 +1,29 @@
using Content.Server.Popups;
using Content.Shared._White.Cult.Pylon;
using Content.Shared.Construction;
using Content.Shared.Popups;
using JetBrains.Annotations;
namespace Content.Server._White.Cult.Pylon;
[UsedImplicitly]
[DataDefinition]
public sealed partial class CheckForStructure : IGraphAction
{
public void PerformAction(EntityUid uid, EntityUid? userUid, IEntityManager entityManager)
{
var xform = entityManager.GetComponent<TransformComponent>(uid);
var coords = xform.Coordinates;
if (!SharedPylonComponent.CheckForStructure(coords, entityManager, 9f, uid))
return;
entityManager.QueueDeleteEntity(uid);
if (userUid != null)
{
entityManager.System<PopupSystem>()
.PopupEntity(Loc.GetString("cult-structure-craft-another-structure-nearby"),
userUid.Value, userUid.Value, PopupType.MediumCaution);
}
entityManager.SpawnEntity("CultRunicMetal4", coords);
}
}

View File

@@ -61,15 +61,6 @@ public sealed class PylonSystem : EntitySystem
private void OnInit(EntityUid uid, SharedPylonComponent component, ComponentInit args) private void OnInit(EntityUid uid, SharedPylonComponent component, ComponentInit args)
{ {
var coords = Transform(uid).Coordinates;
if (SharedPylonComponent.CheckForStructure(coords, EntityManager, 9f, uid))
{
QueueDel(uid);
_popupSystem.PopupCoordinates(Loc.GetString("cult-structure-craft-another-structure-nearby"),
coords, PopupType.MediumCaution);
Spawn("CultRunicMetal4", coords);
return;
}
UpdateAppearance(uid, component); UpdateAppearance(uid, component);
} }

View File

@@ -102,6 +102,8 @@ public partial class CultSystem
{ {
_popupSystem.PopupEntity("Цель обезмолвлена.", args.User, args.User); _popupSystem.PopupEntity("Цель обезмолвлена.", args.User, args.User);
} }
if (args.Speech != null)
_chat.TrySendInGameICMessage(args.User, args.Speech, InGameICChatType.Whisper, false);
return; return;
} }
@@ -369,8 +371,8 @@ public partial class CultSystem
if (!TryComp(args.Target, out CuffableComponent? cuffs) || cuffs.Container.ContainedEntities.Count > 0) if (!TryComp(args.Target, out CuffableComponent? cuffs) || cuffs.Container.ContainedEntities.Count > 0)
return; return;
var doAfterArgs = new DoAfterArgs(EntityManager, args.Performer, TimeSpan.FromSeconds(2), new ShacklesEvent(), var doAfterArgs = new DoAfterArgs(EntityManager, args.Performer, TimeSpan.FromSeconds(2),
args.Performer, args.Target) new ShacklesEvent(args.Speech), args.Performer, args.Target)
{ {
BreakOnMove = true, BreakOnMove = true,
BreakOnDamage = true BreakOnDamage = true
@@ -379,7 +381,6 @@ public partial class CultSystem
if (!_doAfterSystem.TryStartDoAfter(doAfterArgs)) if (!_doAfterSystem.TryStartDoAfter(doAfterArgs))
return; return;
Speak(args);
args.Handled = true; args.Handled = true;
} }

View File

@@ -7,7 +7,6 @@ using Content.Shared.Wieldable;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Network; using Robust.Shared.Network;
using Robust.Shared.Timing;
namespace Content.Shared.Item.ItemToggle; namespace Content.Shared.Item.ItemToggle;
/// <summary> /// <summary>
@@ -23,7 +22,6 @@ public abstract class SharedItemToggleSystem : EntitySystem
[Dependency] private readonly SharedPointLightSystem _light = default!; [Dependency] private readonly SharedPointLightSystem _light = default!;
[Dependency] private readonly INetManager _netManager = default!; [Dependency] private readonly INetManager _netManager = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly IGameTiming _timing = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -242,17 +240,14 @@ public abstract class SharedItemToggleSystem : EntitySystem
/// </summary> /// </summary>
private void UpdateActiveSound(EntityUid uid, ItemToggleActiveSoundComponent activeSound, ref ItemToggledEvent args) private void UpdateActiveSound(EntityUid uid, ItemToggleActiveSoundComponent activeSound, ref ItemToggledEvent args)
{ {
if (!_timing.IsFirstTimePredicted) // WD if (_netManager.IsClient) // WD EDIT, FUCK THIS (desword sound broken)
return; return;
if (args.Activated) if (args.Activated)
{ {
if (activeSound.ActiveSound != null && activeSound.PlayingStream == null) if (activeSound.ActiveSound != null && activeSound.PlayingStream == null)
{ {
if (args.Predicted) activeSound.PlayingStream = _audio.PlayPvs(activeSound.ActiveSound, uid, AudioParams.Default.WithLoop(true)) .Value.Entity;
activeSound.PlayingStream = _audio.PlayPredicted(activeSound.ActiveSound, uid, args.User, AudioParams.Default.WithLoop(true)).Value.Entity;
else
activeSound.PlayingStream = _audio.PlayPvs(activeSound.ActiveSound, uid, AudioParams.Default.WithLoop(true)).Value.Entity;
} }
} }
else else

View File

@@ -11,7 +11,6 @@ using Content.Shared._White.Wizard.Timestop;
using Content.Shared.Buckle; using Content.Shared.Buckle;
using Content.Shared.Buckle.Components; using Content.Shared.Buckle.Components;
using Content.Shared.Mobs; using Content.Shared.Mobs;
using Content.Shared.Movement.Events;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Input.Binding; using Robust.Shared.Input.Binding;
using Robust.Shared.Physics; using Robust.Shared.Physics;
@@ -29,10 +28,8 @@ public abstract partial class SharedStandingStateSystem : EntitySystem
[Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!; // WD EDIT [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; // WD EDIT
[Dependency] private readonly MovementSpeedModifierSystem _movement = default!; // WD EDIT [Dependency] private readonly MovementSpeedModifierSystem _movement = default!; // WD EDIT
[Dependency] private readonly SharedStunSystem _stun = default!; // WD EDIT
[Dependency] private readonly MobStateSystem _mobState = default!; // WD EDIT [Dependency] private readonly MobStateSystem _mobState = default!; // WD EDIT
[Dependency] private readonly SharedBuckleSystem _buckle = default!; // WD EDIT [Dependency] private readonly SharedBuckleSystem _buckle = default!; // WD EDIT
[Dependency] private readonly SharedTransformSystem _transform = default!; // WD EDIT
[Dependency] private readonly SharedRotationVisualsSystem _rotation = default!; // WD EDIT [Dependency] private readonly SharedRotationVisualsSystem _rotation = default!; // WD EDIT
// If StandingCollisionLayer value is ever changed to more than one layer, the logic needs to be edited. // If StandingCollisionLayer value is ever changed to more than one layer, the logic needs to be edited.
@@ -53,7 +50,6 @@ public abstract partial class SharedStandingStateSystem : EntitySystem
SubscribeLocalEvent<StandingStateComponent, StandingUpDoAfterEvent>(OnStandingUpDoAfter); SubscribeLocalEvent<StandingStateComponent, StandingUpDoAfterEvent>(OnStandingUpDoAfter);
SubscribeLocalEvent<StandingStateComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovementSpeed); SubscribeLocalEvent<StandingStateComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovementSpeed);
SubscribeLocalEvent<StandingStateComponent, TileFrictionEvent>(OnTileFriction);
SubscribeLocalEvent<StandingStateComponent, SlipAttemptEvent>(OnSlipAttempt); SubscribeLocalEvent<StandingStateComponent, SlipAttemptEvent>(OnSlipAttempt);
InitializeColliding(); InitializeColliding();
@@ -114,12 +110,6 @@ public abstract partial class SharedStandingStateSystem : EntitySystem
args.ModifySpeed(1f, 1f); args.ModifySpeed(1f, 1f);
} }
private void OnTileFriction(Entity<StandingStateComponent> ent, ref TileFrictionEvent args)
{
if (IsDown(ent))
args.Modifier *= SharedStunSystem.KnockDownModifier;
}
private void OnSlipAttempt(EntityUid uid, StandingStateComponent component, SlipAttemptEvent args) private void OnSlipAttempt(EntityUid uid, StandingStateComponent component, SlipAttemptEvent args)
{ {
if (IsDown(uid)) if (IsDown(uid))
@@ -171,7 +161,7 @@ public abstract partial class SharedStandingStateSystem : EntitySystem
return true; return true;
} }
public enum DropHeldItemsBehavior public enum DropHeldItemsBehavior : byte
{ {
NoDrop, NoDrop,
DropIfStanding, DropIfStanding,
@@ -222,9 +212,6 @@ public abstract partial class SharedStandingStateSystem : EntitySystem
if (TryComp(uid, out BuckleComponent? buckle) && buckle.Buckled && !_buckle.TryUnbuckle(uid, uid, buckleComp: buckle)) // WD EDIT if (TryComp(uid, out BuckleComponent? buckle) && buckle.Buckled && !_buckle.TryUnbuckle(uid, uid, buckleComp: buckle)) // WD EDIT
return false; return false;
if (standingState.CurrentState is StandingState.Lying or StandingState.GettingUp)
return true;
// This is just to avoid most callers doing this manually saving boilerplate // This is just to avoid most callers doing this manually saving boilerplate
// 99% of the time you'll want to drop items but in some scenarios (e.g. buckling) you don't want to. // 99% of the time you'll want to drop items but in some scenarios (e.g. buckling) you don't want to.
// We do this BEFORE downing because something like buckle may be blocking downing but we want to drop hand items anyway // We do this BEFORE downing because something like buckle may be blocking downing but we want to drop hand items anyway
@@ -234,6 +221,9 @@ public abstract partial class SharedStandingStateSystem : EntitySystem
RaiseLocalEvent(uid, new DropHandItemsEvent()); RaiseLocalEvent(uid, new DropHandItemsEvent());
} }
if (standingState.CurrentState is StandingState.Lying or StandingState.GettingUp)
return true;
var msg = new DownAttemptEvent(); var msg = new DownAttemptEvent();
RaiseLocalEvent(uid, msg); RaiseLocalEvent(uid, msg);

View File

@@ -107,7 +107,7 @@ public abstract class SharedStunSystem : EntitySystem
private void OnKnockInit(EntityUid uid, KnockedDownComponent component, ComponentInit args) private void OnKnockInit(EntityUid uid, KnockedDownComponent component, ComponentInit args)
{ {
RaiseNetworkEvent(new CheckAutoGetUpEvent()); // WD EDIT RaiseNetworkEvent(new CheckAutoGetUpEvent()); // WD EDIT
_standingState.Down(uid); _standingState.TryLieDown(uid, null, SharedStandingStateSystem.DropHeldItemsBehavior.DropIfStanding);
} }
private void OnKnockShutdown(EntityUid uid, KnockedDownComponent component, ComponentShutdown args) private void OnKnockShutdown(EntityUid uid, KnockedDownComponent component, ComponentShutdown args)
@@ -207,6 +207,9 @@ public abstract class SharedStunSystem : EntitySystem
if (_statusEffect.HasStatusEffect(uid, "Stun")) if (_statusEffect.HasStatusEffect(uid, "Stun"))
time = TimeSpan.FromSeconds(6); time = TimeSpan.FromSeconds(6);
if (_standingState.IsDown(uid)) // WD
RaiseLocalEvent(uid, new DropHandItemsEvent());
return TryKnockdown(uid, time, refresh, status) && TryStun(uid, time, refresh, status); return TryKnockdown(uid, time, refresh, status) && TryStun(uid, time, refresh, status);
} }

View File

@@ -129,7 +129,7 @@ public sealed partial class MeleeWeaponComponent : Component
/// Nearest edge range to hit an entity. /// Nearest edge range to hit an entity.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public float Range = 1.2f; public float Range = 1.5f;
/// <summary> /// <summary>
/// Total width of the angle for wide attacks. /// Total width of the angle for wide attacks.

View File

@@ -401,7 +401,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
if (lightTarget == null) if (lightTarget == null)
{ {
if (weapon.CanMiss) if (weapon.CanMiss || session == null) // NPCs can miss
break; break;
return false; return false;
} }
@@ -512,11 +512,6 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
animation = miss && weapon.Animation == "WeaponArcThrust" animation = miss && weapon.Animation == "WeaponArcThrust"
? weapon.MissAnimation ? weapon.MissAnimation
: weapon.Animation; : weapon.Animation;
if (miss)
{
weapon.NextAttack -= fireRate / 2f;
weapon.NextMobAttack -= fireRate / 2f;
}
// WD EDIT END // WD EDIT END
break; break;
case DisarmAttackEvent disarm: case DisarmAttackEvent disarm:

View File

@@ -1,4 +1,5 @@
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.Standing;
using Content.Shared.Stunnable; using Content.Shared.Stunnable;
namespace Content.Shared._White.BuffedFlashGrenade; namespace Content.Shared._White.BuffedFlashGrenade;
@@ -38,9 +39,12 @@ public sealed class FlashSoundSuppressionSystem : EntitySystem
if (distance > range) if (distance > range)
return; return;
var knockdownTime = float.Lerp(knockdownDuration, 0f, distance / range); if (TryComp<StandingStateComponent>(target, out var standingState) && standingState.CanLieDown)
if (knockdownTime > 0f) {
_stunSystem.TryKnockdown(target, TimeSpan.FromSeconds(knockdownTime), true); var knockdownTime = float.Lerp(knockdownDuration, 0f, distance / range);
if (knockdownTime > 0f)
_stunSystem.TryKnockdown(target, TimeSpan.FromSeconds(knockdownTime), true);
}
var stunTime = float.Lerp(stunDuration, 0f, distance / range); var stunTime = float.Lerp(stunDuration, 0f, distance / range);
if (stunTime > 0f) if (stunTime > 0f)

View File

@@ -6,8 +6,16 @@ using Robust.Shared.Serialization;
namespace Content.Shared._White.Cult.Actions; namespace Content.Shared._White.Cult.Actions;
[Serializable, NetSerializable] [Serializable, NetSerializable]
public sealed partial class ShacklesEvent : SimpleDoAfterEvent public sealed partial class ShacklesEvent : DoAfterEvent
{ {
public string? Speech;
public ShacklesEvent(string? speech)
{
Speech = speech;
}
public override DoAfterEvent Clone() => this;
} }
[Serializable, NetSerializable] [Serializable, NetSerializable]

View File

@@ -49,7 +49,7 @@ public sealed class BloodSpearSystem : EntitySystem
if (!_holy.IsHoldingHolyWeapon(args.Target)) if (!_holy.IsHoldingHolyWeapon(args.Target))
{ {
if(!_stunSystem.TryParalyze(args.Target, TimeSpan.FromSeconds(4), true, status)) if(!_stunSystem.TryParalyze(args.Target, TimeSpan.FromSeconds(5), true, status))
return; return;
} }

View File

@@ -6,10 +6,10 @@ ent-SoulShardGhost = камень душ
.suffix = Роль призраков .suffix = Роль призраков
ent-StunHand = оглушающая аура ent-StunHand = оглушающая аура
.desc = Оглушит и обезмолвит жертву при ударе. .desc = Оглушит и обезмолвит жертву при контакте.
ent-RitesHand = аура кровавых обрядов ent-RitesHand = аура кровавых обрядов
.desc = Впитывает кровь из всего, к чему прикасается. При ударе по культистам и конструктам может исцелить их. Используйте в руке, чтобы провести продвинутый обряд. .desc = Впитывает кровь из всего, к чему прикасается. При контакте с культистами или конструктами может исцелить их. Используйте в руке, чтобы провести продвинутый обряд.
ent-ShadowShackles = теневые оковы ent-ShadowShackles = теневые оковы
.desc = Оковы, сковывающие запястья с помощью зловещей магии. .desc = Оковы, сковывающие запястья с помощью зловещей магии.

View File

@@ -22,3 +22,5 @@ melee-block-event-blocked = заблокировал!
alerts-blocked-name = Атака заблокирована alerts-blocked-name = Атака заблокирована
alerts-blocked-desc = Невозможно блокировать некоторое время. alerts-blocked-desc = Невозможно блокировать некоторое время.
melee-block-component-delay = Может блокировать атаку ближнего боя каждые {$delay} секунд. melee-block-component-delay = Может блокировать атаку ближнего боя каждые {$delay} секунд.
context-menu-cant-interact = Невозможно взаимодействовать через контекстное меню!

View File

@@ -112,12 +112,7 @@
components: components:
- type: StorageFill - type: StorageFill
contents: contents:
- id: Crowbar - id: ClothingBeltUtilityEngineering
- id: Wrench
- id: Screwdriver
- id: Wirecutter
- id: Welder
- id: Multitool
- id: ClothingHandsGlovesCombat - id: ClothingHandsGlovesCombat
- id: ClothingMaskGasSyndicate - id: ClothingMaskGasSyndicate

View File

@@ -375,7 +375,8 @@
damageType: Blunt damageType: Blunt
damage: 10 damage: 10
behaviors: behaviors:
- !type:GibBehavior { } - !type:GibBehavior
recursive: false
- type: NonSpreaderZombie - type: NonSpreaderZombie
- type: entity - type: entity
@@ -529,7 +530,8 @@
damageType: Blunt damageType: Blunt
damage: 60 damage: 60
behaviors: behaviors:
- !type:GibBehavior { } - !type:GibBehavior
recursive: false
- type: FireVisuals - type: FireVisuals
sprite: Mobs/Effects/onfire.rsi sprite: Mobs/Effects/onfire.rsi
normalState: Mouse_burning normalState: Mouse_burning

View File

@@ -757,7 +757,7 @@
- type: FlashOnTrigger - type: FlashOnTrigger
range: 7 range: 7
stunTime: 2 # WD stunTime: 2 # WD
knockdownTime: 20 # WD knockdownTime: 10 # WD
- type: SpawnOnTrigger - type: SpawnOnTrigger
proto: GrenadeFlashEffect proto: GrenadeFlashEffect
- type: ActiveTimerTrigger - type: ActiveTimerTrigger

View File

@@ -42,7 +42,7 @@
animation: WeaponArcThrust animation: WeaponArcThrust
soundHit: soundHit:
path: /Audio/Weapons/bladeslice.ogg path: /Audio/Weapons/bladeslice.ogg
range: 1.8 # Spears are long range: 2 # Spears are long
- type: DamageOtherOnHit - type: DamageOtherOnHit
damage: damage:
types: types:

View File

@@ -68,7 +68,7 @@
- type: FlashOnTrigger - type: FlashOnTrigger
range: 7 range: 7
stunTime: 2 # WD stunTime: 2 # WD
knockdownTime: 20 # WD knockdownTime: 10 # WD
- type: SoundOnTrigger - type: SoundOnTrigger
sound: sound:
path: "/Audio/Effects/flash_bang.ogg" path: "/Audio/Effects/flash_bang.ogg"

View File

@@ -200,7 +200,7 @@
mask: mask:
- FullTileMask - FullTileMask
layer: layer:
- WallLayer - GlassLayer
- type: Construction - type: Construction
graph: GrilleDiagonal graph: GrilleDiagonal
node: grilleDiagonal node: grilleDiagonal
@@ -235,7 +235,7 @@
mask: mask:
- FullTileMask - FullTileMask
layer: layer:
- WallLayer - GlassLayer
- type: Construction - type: Construction
graph: GrilleDiagonal graph: GrilleDiagonal
node: clockworkGrilleDiagonal node: clockworkGrilleDiagonal

View File

@@ -101,6 +101,7 @@
blacklist: blacklist:
tags: tags:
- NukeOpsUplink - NukeOpsUplink
saleLimit: 1
# Night Vision # Night Vision
- type: listing - type: listing

View File

@@ -87,6 +87,7 @@
completed: completed:
- !type:SnapToGrid - !type:SnapToGrid
southRotation: true southRotation: true
- !type:CheckForStructure
steps: steps:
- material: RunicMetalSheets - material: RunicMetalSheets
amount: 4 amount: 4

View File

@@ -8,15 +8,6 @@
components: components:
- type: Item - type: Item
size: Ginormous size: Ginormous
- type: MeleeWeapon
canBeBlocked: false
canHeavyAttack: false
canMiss: false
attackRate: 2
wideAnimationRotation: 180
damage:
types:
Heat: 0
- type: DeleteOnDropAttempt - type: DeleteOnDropAttempt
message: cult-hand-component-extra-message message: cult-hand-component-extra-message
- type: Unremoveable - type: Unremoveable
@@ -35,15 +26,6 @@
state: icon state: icon
- type: Item - type: Item
sprite: White/Cult/Entities/stun.rsi sprite: White/Cult/Entities/stun.rsi
- type: MeleeWeapon
canAttackSelf: false
attackWhitelist:
components:
- StatusEffects
attackBlacklist:
components:
- Cultist
- Construct
- type: CultStunHand - type: CultStunHand
speech: "Fuu ma'jin!" speech: "Fuu ma'jin!"
@@ -58,11 +40,6 @@
state: icon state: icon
- type: Item - type: Item
sprite: White/Cult/Entities/rites.rsi sprite: White/Cult/Entities/rites.rsi
- type: MeleeWeapon
attackWhitelist:
components:
- Cultist
- Construct
- type: CultRitesHand - type: CultRitesHand
speech: "Fel'th Dol Ab'orod!" speech: "Fel'th Dol Ab'orod!"
- type: ActivatableUI - type: ActivatableUI

View File

@@ -35,7 +35,7 @@
animation: WeaponArcThrust animation: WeaponArcThrust
soundHit: soundHit:
path: /Audio/Weapons/bladeslice.ogg path: /Audio/Weapons/bladeslice.ogg
range: 1.8 range: 2
- type: DamageOtherOnHit - type: DamageOtherOnHit
damage: damage:
types: types:

View File

@@ -84,6 +84,7 @@
group: Construct group: Construct
- type: GlobalAntagonist - type: GlobalAntagonist
antagonistPrototype: globalAntagonistCult antagonistPrototype: globalAntagonistCult
- type: ThermalBlocker
- type: entity - type: entity
id: JuggernautConstruct id: JuggernautConstruct

View File

@@ -41,7 +41,7 @@
- type: FlashOnTrigger - type: FlashOnTrigger
range: 5 range: 5
stunTime: 2 # WD stunTime: 2 # WD
knockdownTime: 20 # WD knockdownTime: 10 # WD
- type: SpawnOnTrigger - type: SpawnOnTrigger
proto: GrenadeFlashEffect proto: GrenadeFlashEffect
- type: DeleteOnTrigger - type: DeleteOnTrigger

View File

@@ -265,7 +265,7 @@
- type: MeleeWeapon - type: MeleeWeapon
soundHit: soundHit:
path: /Audio/White/Items/hit/chainhit.ogg path: /Audio/White/Items/hit/chainhit.ogg
range: 2.2 range: 2.5
damage: damage:
types: types:
Blunt: 18 Blunt: 18

View File

@@ -3,7 +3,7 @@
alias: alias:
- survival - survival
name: survival-title name: survival-title
showInVote: false # secret showInVote: true
description: survival-description description: survival-description
rules: rules:
- RampingStationEventScheduler - RampingStationEventScheduler
@@ -98,7 +98,7 @@
- traitor - traitor
name: traitor-title name: traitor-title
description: traitor-description description: traitor-description
showInVote: false showInVote: true
rules: rules:
- Traitor - Traitor
- SubGamemodesRule - SubGamemodesRule
@@ -114,7 +114,7 @@
name: death-match-title name: death-match-title
description: death-match-description description: death-match-description
maxPlayers: 15 maxPlayers: 15
showInVote: true showInVote: false
supportedMaps: DeathMatchMapPool supportedMaps: DeathMatchMapPool
rules: rules:
- DeathMatch31 - DeathMatch31
@@ -141,7 +141,7 @@
- revolutionaries - revolutionaries
name: rev-title name: rev-title
description: rev-description description: rev-description
showInVote: false showInVote: true
rules: rules:
- Revolutionary - Revolutionary
- SubGamemodesRule - SubGamemodesRule
@@ -172,7 +172,7 @@
- pirates - pirates
name: pirates-title name: pirates-title
description: pirates-description description: pirates-description
showInVote: true showInVote: false
rules: rules:
- Pirates - Pirates
- BasicStationEventScheduler - BasicStationEventScheduler

View File

@@ -5,7 +5,7 @@
Changeling: 0.14 Changeling: 0.14
Nukeops: 0.14 Nukeops: 0.14
Cult: 0.15 Cult: 0.15
Wizard: 0.15 Wizard: 0.09
Revolutionary: 0.04 Revolutionary: 0.1
Zombie: 0.04 Zombie: 0.04
Survival: 0.04 Survival: 0.04