@@ -19,7 +19,7 @@ public sealed class FleshAnomalyComponent : Component
|
||||
/// scales with severity.
|
||||
/// </summary>
|
||||
[DataField("maxSpawnAmount"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public int MaxSpawnAmount = 8;
|
||||
public int MaxSpawnAmount = 7;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum radius the entities will spawn in.
|
||||
@@ -27,7 +27,7 @@ public sealed class FleshAnomalyComponent : Component
|
||||
/// scales with stability
|
||||
/// </summary>
|
||||
[DataField("spawnRange"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public float SpawnRange = 4f;
|
||||
public float SpawnRange = 5f;
|
||||
|
||||
/// <summary>
|
||||
/// The tile that is spawned by the anomaly's effect
|
||||
|
||||
20
Content.Shared/Damage/Components/DamageContactsComponent.cs
Normal file
20
Content.Shared/Damage/Components/DamageContactsComponent.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Damage.Components;
|
||||
|
||||
[NetworkedComponent, RegisterComponent]
|
||||
public sealed class DamageContactsComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The damage done each second to those touching this entity
|
||||
/// </summary>
|
||||
[DataField("damage", required: true)]
|
||||
public DamageSpecifier Damage = new();
|
||||
|
||||
/// <summary>
|
||||
/// Entities that aren't damaged by this entity
|
||||
/// </summary>
|
||||
[DataField("ignoreWhitelist")]
|
||||
public EntityWhitelist? IgnoreWhitelist;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Shared.Damage.Components;
|
||||
|
||||
[NetworkedComponent, RegisterComponent]
|
||||
public sealed class DamagedByContactComponent : Component
|
||||
{
|
||||
[DataField("nextSecond", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan NextSecond = TimeSpan.Zero;
|
||||
|
||||
[ViewVariables]
|
||||
public DamageSpecifier? Damage;
|
||||
}
|
||||
72
Content.Shared/Damage/Systems/DamageContactsSystem.cs
Normal file
72
Content.Shared/Damage/Systems/DamageContactsSystem.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using Content.Shared.Damage.Components;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Physics.Events;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Shared.Damage.Systems;
|
||||
|
||||
public sealed class DamageContactsSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<DamageContactsComponent, StartCollideEvent>(OnEntityEnter);
|
||||
SubscribeLocalEvent<DamageContactsComponent, EndCollideEvent>(OnEntityExit);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
foreach (var damaged in EntityQuery<DamagedByContactComponent>())
|
||||
{
|
||||
var ent = damaged.Owner;
|
||||
if (_timing.CurTime < damaged.NextSecond)
|
||||
continue;
|
||||
damaged.NextSecond = _timing.CurTime + TimeSpan.FromSeconds(1);
|
||||
|
||||
if (damaged.Damage != null)
|
||||
_damageable.TryChangeDamage(ent, damaged.Damage, interruptsDoAfters: false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEntityExit(EntityUid uid, DamageContactsComponent component, ref EndCollideEvent args)
|
||||
{
|
||||
var otherUid = args.OtherFixture.Body.Owner;
|
||||
|
||||
if (!TryComp<PhysicsComponent>(uid, out var body))
|
||||
return;
|
||||
|
||||
var damageQuery = GetEntityQuery<DamageContactsComponent>();
|
||||
foreach (var contact in _physics.GetContactingEntities(body))
|
||||
{
|
||||
var ent = contact.Owner;
|
||||
if (ent == uid)
|
||||
continue;
|
||||
|
||||
if (damageQuery.HasComponent(ent))
|
||||
return;
|
||||
}
|
||||
|
||||
RemComp<DamagedByContactComponent>(otherUid);
|
||||
}
|
||||
|
||||
private void OnEntityEnter(EntityUid uid, DamageContactsComponent component, ref StartCollideEvent args)
|
||||
{
|
||||
var otherUid = args.OtherFixture.Body.Owner;
|
||||
|
||||
if (HasComp<DamagedByContactComponent>(otherUid))
|
||||
return;
|
||||
|
||||
if (component.IgnoreWhitelist?.IsValid(otherUid) ?? false)
|
||||
return;
|
||||
|
||||
var damagedByContact = EnsureComp<DamagedByContactComponent>(otherUid);
|
||||
damagedByContact.Damage = component.Damage;
|
||||
}
|
||||
}
|
||||
@@ -122,10 +122,17 @@
|
||||
acts: [ "Destruction" ]
|
||||
- type: Spreader
|
||||
growthResult: FleshKudzu
|
||||
chance: 1
|
||||
- type: SlowContacts
|
||||
walkSpeedModifier: 0.2
|
||||
sprintSpeedModifier: 0.2
|
||||
chance: 0.5
|
||||
- type: DamageContacts
|
||||
damage:
|
||||
types:
|
||||
Slash: 1.5
|
||||
ignoreWhitelist:
|
||||
tags:
|
||||
- Flesh
|
||||
- type: SlowContacts
|
||||
walkSpeedModifier: 0.3
|
||||
sprintSpeedModifier: 0.3
|
||||
ignoreWhitelist:
|
||||
tags:
|
||||
- Flesh
|
||||
|
||||
Reference in New Issue
Block a user