Skip to content

Commit 21c210b

Browse files
committed
Add gore and item drop on consumption, fix spray crash in debug
1 parent be4edd9 commit 21c210b

File tree

6 files changed

+95
-7
lines changed

6 files changed

+95
-7
lines changed

Content.Server/Chemistry/TileReactions/CleanTileReaction.cs

+8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Content.Shared.Chemistry.Reagent;
55
using Content.Shared.FixedPoint;
66
using Content.Shared.Fluids.Components;
7+
using Content.Shared.Tag;
78
using Robust.Shared.Map;
89
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
910
using System.Linq;
@@ -35,13 +36,20 @@ FixedPoint2 ITileReaction.TileReact(TileRef tile, ReagentPrototype reagent, Fixe
3536
{
3637
var entMan = IoCManager.Resolve<IEntityManager>();
3738
var entities = entMan.System<EntityLookupSystem>().GetLocalEntitiesIntersecting(tile, 0f).ToArray();
39+
var tags = entMan.System<TagSystem>();
3840
var puddleQuery = entMan.GetEntityQuery<PuddleComponent>();
3941
var solutionContainerSystem = entMan.System<SolutionContainerSystem>();
4042
// Multiply as the amount we can actually purge is higher than the react amount.
4143
var purgeAmount = reactVolume / CleanAmountMultiplier;
4244

4345
foreach (var entity in entities)
4446
{
47+
if (tags.HasTag(entity, "ReactionCleanable"))
48+
{
49+
entMan.QueueDeleteEntity(entity);
50+
continue;
51+
}
52+
4553
if (!puddleQuery.TryGetComponent(entity, out var puddle) ||
4654
!solutionContainerSystem.TryGetSolution(entity, puddle.SolutionName, out var puddleSolution, out _))
4755
{

Content.Server/Fluids/EntitySystems/SpraySystem.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using Content.Server.Fluids.Components;
66
using Content.Server.Gravity;
77
using Content.Server.Popups;
8-
using Content.Shared.Disposal.Components;
98
using Content.Shared.FixedPoint;
109
using Content.Shared.Interaction;
1110
using Content.Shared.Timing;
@@ -16,6 +15,7 @@
1615
using Robust.Shared.Physics.Components;
1716
using Robust.Shared.Prototypes;
1817
using System.Numerics;
18+
using Content.Server.Disposal.Unit.Components;
1919

2020
namespace Content.Server.Fluids.EntitySystems;
2121

@@ -44,12 +44,14 @@ private void OnAfterInteract(Entity<SprayComponent> entity, ref AfterInteractEve
4444
if (args.Handled)
4545
return;
4646

47+
// SS220 Placeable-Spray begin
4748
//do not spray on table and disposal unit
4849
if (HasComp<PlaceableSurfaceComponent>(args.Target)
49-
|| HasComp<SharedDisposalUnitComponent>(args.Target))
50+
|| HasComp<DisposalUnitComponent>(args.Target))
5051
{
5152
return;
5253
}
54+
// SS220 Placeable-Spray end
5355

5456
args.Handled = true;
5557

Content.Server/SS220/DarkReaper/DarkReaperSystem.cs

+42-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
2+
using System.Numerics;
23
using Content.Server.Actions;
34
using Content.Server.AlertLevel;
45
using Content.Server.Chat.Systems;
@@ -8,9 +9,12 @@
89
using Content.Server.Station.Systems;
910
using Content.Shared.Alert;
1011
using Content.Shared.Damage;
12+
using Content.Shared.Inventory;
1113
using Content.Shared.Mobs.Systems;
1214
using Content.Shared.SS220.DarkReaper;
1315
using Robust.Shared.Containers;
16+
using Robust.Shared.Physics.Systems;
17+
using Robust.Shared.Random;
1418
using Robust.Shared.Utility;
1519

1620
namespace Content.Server.SS220.DarkReaper;
@@ -28,6 +32,10 @@ public sealed class DarkReaperSystem : SharedDarkReaperSystem
2832
[Dependency] private readonly StationSystem _station = default!;
2933
[Dependency] private readonly AlertLevelSystem _alertLevel = default!;
3034
[Dependency] private readonly ChatSystem _chat = default!;
35+
[Dependency] private readonly InventorySystem _inventory = default!;
36+
[Dependency] private readonly SharedTransformSystem _transform = default!;
37+
[Dependency] private readonly IRobustRandom _random = default!;
38+
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
3139

3240
private readonly ISawmill _sawmill = Logger.GetSawmill("DarkReaper");
3341

@@ -69,18 +77,47 @@ protected override void OnAfterConsumed(EntityUid uid, DarkReaperComponent comp,
6977
{
7078
if (comp.PhysicalForm && target.IsValid() && !EntityManager.IsQueuedForDeletion(target) && _mobState.IsDead(target))
7179
{
72-
if (_container.TryGetContainer(uid, DarkReaperComponent.ConsumedContainerId, out var container))
80+
if (!_container.TryGetContainer(uid, DarkReaperComponent.ConsumedContainerId, out var container))
81+
return;
82+
83+
if (!_container.CanInsert(target, container))
84+
return;
85+
86+
// spawn gore
87+
Spawn(comp.EntityToSpawnAfterConsuming, Transform(target).Coordinates);
88+
89+
// randomly drop inventory items
90+
if (_inventory.TryGetContainerSlotEnumerator(target, out var slots))
7391
{
74-
_container.Insert(target, container);
92+
while (slots.MoveNext(out var containerSlot))
93+
{
94+
if (containerSlot.ContainedEntity is not { } containedEntity)
95+
continue;
96+
97+
if (!_random.Prob(comp.InventoryDropProbabilityOnConsumed))
98+
continue;
99+
100+
if (!_container.TryRemoveFromContainer(containedEntity))
101+
continue;
102+
103+
// set random rotation
104+
_transform.SetLocalRotationNoLerp(containedEntity, Angle.FromDegrees(_random.NextDouble(0, 360)));
105+
106+
// apply random impulse
107+
var maxAxisImp = comp.SpawnOnDeathImpulseStrength;
108+
var impulseVec = new Vector2(_random.NextFloat(-maxAxisImp, maxAxisImp), _random.NextFloat(-maxAxisImp, maxAxisImp));
109+
_physics.ApplyLinearImpulse(containedEntity, impulseVec);
110+
}
75111
}
76112

113+
_container.Insert(target, container);
77114
_damageable.TryChangeDamage(uid, comp.HealPerConsume, true, origin: args.Args.User);
78115

79116
comp.Consumed++;
80-
81117
var stageBefore = comp.CurrentStage;
82118
UpdateStage(uid, comp);
83-
// warn a crew
119+
120+
// warn a crew if alert stage is reached
84121
if (comp.CurrentStage > stageBefore && comp.CurrentStage == comp.AlertStage)
85122
{
86123
var reaperXform = Transform(uid);
@@ -93,6 +130,7 @@ protected override void OnAfterConsumed(EntityUid uid, DarkReaperComponent comp,
93130
_chat.DispatchStationAnnouncement(stationUid ?? uid, announcement, sender, false, Color.Red);
94131
}
95132

133+
// update consoom counter alert
96134
UpdateAlert(uid, comp);
97135
Dirty(uid, comp);
98136
}

Content.Shared/SS220/DarkReaper/DarkReaperComponent.cs

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
22
using Content.Shared.Damage;
3+
using Content.Shared.Decals;
34
using Content.Shared.FixedPoint;
45
using Robust.Shared.Audio;
56
using Robust.Shared.GameStates;
@@ -184,9 +185,23 @@ public sealed partial class DarkReaperComponent : Component
184185
MaxDistance = 8
185186
});
186187

187-
[ViewVariables, DataField]
188+
[ViewVariables(VVAccess.ReadOnly), DataField]
188189
public DamageSpecifier HealPerConsume = new();
189190

191+
/// <summary>
192+
/// Entity that spawns when dark reaper consumes people.
193+
/// Intended to be a replacement for giblets, as dark reaper no longer gibs people.
194+
/// </summary>
195+
[ViewVariables(VVAccess.ReadWrite), DataField]
196+
public EntProtoId EntityToSpawnAfterConsuming = "SS220Gore";
197+
198+
/// <summary>
199+
/// Probability than item in inventory slot gets dropped when target is consumed.
200+
/// Rolls for each inventory slot.
201+
/// </summary>
202+
[ViewVariables(VVAccess.ReadWrite), DataField(serverOnly: true)]
203+
public float InventoryDropProbabilityOnConsumed = 0.5f;
204+
190205
/// STAGE PROGRESSION
191206

192207
[ViewVariables, DataField, AutoNetworkedField]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
- type: entity
2+
id: SS220Gore
3+
name: кровавые ошмётки
4+
description: Страшно даже подумать о том, что стало с их бывшим владельцем.
5+
components:
6+
- type: Clickable
7+
- type: Physics
8+
bodyType: Static
9+
canCollide: false
10+
- type: Fixtures
11+
fixtures:
12+
fix1:
13+
shape:
14+
!type:PhysShapeAabb {}
15+
- type: Sprite
16+
drawdepth: DeadMobs
17+
sprite: SS220/DemonRofler/dark_reaper.rsi
18+
state: "randomgibs"
19+
noRot: true
20+
- type: Tag
21+
tags:
22+
- ReactionCleanable

Resources/Prototypes/SS220/tags.yml

+3
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@
99

1010
- type: Tag
1111
id: SecDogWearable
12+
13+
- type: Tag
14+
id: ReactionCleanable

0 commit comments

Comments
 (0)