ECS AsteroidRock and add a doafter to mining (#6120)
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
@@ -34,11 +34,12 @@ namespace Content.Client.Entry
|
|||||||
"LightBulb",
|
"LightBulb",
|
||||||
"Healing",
|
"Healing",
|
||||||
"Material",
|
"Material",
|
||||||
|
"RandomAppearance",
|
||||||
|
"Mineable",
|
||||||
"RangedMagazine",
|
"RangedMagazine",
|
||||||
"Ammo",
|
"Ammo",
|
||||||
"AiController",
|
"AiController",
|
||||||
"Computer",
|
"Computer",
|
||||||
"AsteroidRock",
|
|
||||||
"ResearchServer",
|
"ResearchServer",
|
||||||
"ResearchPointSource",
|
"ResearchPointSource",
|
||||||
"ResearchClient",
|
"ResearchClient",
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Content.Server.Weapon.Melee.Components;
|
|
||||||
using Content.Shared.Damage;
|
|
||||||
using Content.Shared.Interaction;
|
|
||||||
using Content.Shared.Mining;
|
|
||||||
using Robust.Shared.Audio;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Player;
|
|
||||||
using Robust.Shared.Random;
|
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
|
|
||||||
namespace Content.Server.Mining.Components
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
public class AsteroidRockComponent : Component, IInteractUsing
|
|
||||||
{
|
|
||||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
|
||||||
|
|
||||||
public override string Name => "AsteroidRock";
|
|
||||||
private static readonly string[] SpriteStates = {"0", "1", "2", "3", "4"};
|
|
||||||
|
|
||||||
protected override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
if (_entMan.TryGetComponent(Owner, out AppearanceComponent? appearance))
|
|
||||||
{
|
|
||||||
appearance.SetData(AsteroidRockVisuals.State, _random.Pick(SpriteStates));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
var item = eventArgs.Using;
|
|
||||||
if (!_entMan.TryGetComponent(item, out MeleeWeaponComponent? meleeWeaponComponent))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
EntitySystem.Get<DamageableSystem>().TryChangeDamage(Owner, meleeWeaponComponent.Damage);
|
|
||||||
|
|
||||||
if (!_entMan.TryGetComponent(item, out PickaxeComponent? pickaxeComponent))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
SoundSystem.Play(Filter.Pvs(Owner), pickaxeComponent.MiningSound.GetSound(), Owner, AudioParams.Default);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
11
Content.Server/Mining/Components/MineableComponent.cs
Normal file
11
Content.Server/Mining/Components/MineableComponent.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Robust.Shared.Analyzers;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Mining.Components;
|
||||||
|
|
||||||
|
[RegisterComponent, ComponentProtoName("Mineable")]
|
||||||
|
[Friend(typeof(MineableSystem))]
|
||||||
|
public class MineableComponent : Component
|
||||||
|
{
|
||||||
|
public float BaseMineTime = 1.0f;
|
||||||
|
}
|
||||||
@@ -1,18 +1,33 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Sound;
|
using Content.Shared.Sound;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
|
|
||||||
namespace Content.Server.Mining.Components
|
namespace Content.Server.Mining.Components
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent, ComponentProtoName("Pickaxe")]
|
||||||
public class PickaxeComponent : Component
|
public class PickaxeComponent : Component
|
||||||
{
|
{
|
||||||
public override string Name => "Pickaxe";
|
[DataField("sound")]
|
||||||
|
|
||||||
[DataField("miningSound")]
|
|
||||||
public SoundSpecifier MiningSound { get; set; } = new SoundPathSpecifier("/Audio/Items/Mining/pickaxe.ogg");
|
public SoundSpecifier MiningSound { get; set; } = new SoundPathSpecifier("/Audio/Items/Mining/pickaxe.ogg");
|
||||||
|
|
||||||
[DataField("miningSpeedMultiplier")]
|
[DataField("timeMultiplier")]
|
||||||
public float MiningSpeedMultiplier { get; set; } = 1f;
|
public float MiningTimeMultiplier { get; set; } = 1f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// What damage should be given to objects when
|
||||||
|
/// mined using a pickaxe?
|
||||||
|
/// </summary>
|
||||||
|
[DataField("damage", required: true)]
|
||||||
|
public DamageSpecifier Damage { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How many entities can this pickaxe mine at once?
|
||||||
|
/// </summary>
|
||||||
|
[DataField("maxEntities")]
|
||||||
|
public int MaxMiningEntities = 1;
|
||||||
|
|
||||||
|
public HashSet<EntityUid> MiningEntities = new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
83
Content.Server/Mining/MineableSystem.cs
Normal file
83
Content.Server/Mining/MineableSystem.cs
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
using Content.Server.DoAfter;
|
||||||
|
using Content.Server.Mining.Components;
|
||||||
|
using Content.Shared.Damage;
|
||||||
|
using Content.Shared.Interaction;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
|
||||||
|
namespace Content.Server.Mining;
|
||||||
|
|
||||||
|
public class MineableSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
|
||||||
|
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<MineableComponent, InteractUsingEvent>(OnInteractUsing);
|
||||||
|
SubscribeLocalEvent<MiningDoafterCancel>(OnDoafterCancel);
|
||||||
|
SubscribeLocalEvent<MiningDoafterSuccess>(OnDoafterSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnInteractUsing(EntityUid uid, MineableComponent component, InteractUsingEvent args)
|
||||||
|
{
|
||||||
|
if (!TryComp<PickaxeComponent>(args.Used, out var pickaxe))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Can't mine too many entities at once.
|
||||||
|
if (pickaxe.MaxMiningEntities < pickaxe.MiningEntities.Count + 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Can't mine one object multiple times.
|
||||||
|
if (!pickaxe.MiningEntities.Add(uid))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var doAfter = new DoAfterEventArgs(args.User, component.BaseMineTime * pickaxe.MiningTimeMultiplier, default, uid)
|
||||||
|
{
|
||||||
|
BreakOnDamage = true,
|
||||||
|
BreakOnStun = true,
|
||||||
|
BreakOnTargetMove = true,
|
||||||
|
BreakOnUserMove = true,
|
||||||
|
MovementThreshold = 0.5f,
|
||||||
|
BroadcastCancelledEvent = new MiningDoafterCancel() { Pickaxe = args.Used, Rock = uid },
|
||||||
|
BroadcastFinishedEvent = new MiningDoafterSuccess() { Pickaxe = args.Used, Rock = uid }
|
||||||
|
};
|
||||||
|
|
||||||
|
_doAfterSystem.DoAfter(doAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDoafterSuccess(MiningDoafterSuccess ev)
|
||||||
|
{
|
||||||
|
if (!TryComp(ev.Pickaxe, out PickaxeComponent? pickaxe))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_damageableSystem.TryChangeDamage(ev.Rock, pickaxe.Damage);
|
||||||
|
SoundSystem.Play(Filter.Pvs(ev.Rock), pickaxe.MiningSound.GetSound(), AudioParams.Default);
|
||||||
|
pickaxe.MiningEntities.Remove(ev.Rock);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDoafterCancel(MiningDoafterCancel ev)
|
||||||
|
{
|
||||||
|
if (!TryComp(ev.Pickaxe, out PickaxeComponent? pickaxe))
|
||||||
|
return;
|
||||||
|
|
||||||
|
pickaxe.MiningEntities.Remove(ev.Rock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// grumble grumble
|
||||||
|
public class MiningDoafterSuccess : EntityEventArgs
|
||||||
|
{
|
||||||
|
public EntityUid Pickaxe;
|
||||||
|
public EntityUid Rock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MiningDoafterCancel : EntityEventArgs
|
||||||
|
{
|
||||||
|
public EntityUid Pickaxe;
|
||||||
|
public EntityUid Rock;
|
||||||
|
}
|
||||||
40
Content.Server/RandomAppearance/RandomAppearanceComponent.cs
Normal file
40
Content.Server/RandomAppearance/RandomAppearanceComponent.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
using Robust.Shared.Analyzers;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Log;
|
||||||
|
using Robust.Shared.Reflection;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
|
|
||||||
|
namespace Content.Server.RandomAppearance;
|
||||||
|
|
||||||
|
[RegisterComponent, ComponentProtoName("RandomAppearance")]
|
||||||
|
[Friend(typeof(RandomAppearanceSystem))]
|
||||||
|
public class RandomAppearanceComponent : Component, ISerializationHooks
|
||||||
|
{
|
||||||
|
[DataField("spriteStates")]
|
||||||
|
public string[] SpriteStates = {"0", "1", "2", "3", "4"};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// What appearance enum key should be set to the random sprite state?
|
||||||
|
/// </summary>
|
||||||
|
[DataField("key", required: true)]
|
||||||
|
public string EnumKeyRaw = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The actual enum after reflection.
|
||||||
|
/// </summary>
|
||||||
|
public System.Enum? EnumKey;
|
||||||
|
|
||||||
|
void ISerializationHooks.AfterDeserialization()
|
||||||
|
{
|
||||||
|
if (IoCManager.Resolve<IReflectionManager>().TryParseEnumReference(EnumKeyRaw, out var @enum))
|
||||||
|
{
|
||||||
|
EnumKey = @enum;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Error($"RandomAppearance enum key {EnumKeyRaw} could not be parsed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
27
Content.Server/RandomAppearance/RandomAppearanceSystem.cs
Normal file
27
Content.Server/RandomAppearance/RandomAppearanceSystem.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Log;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Reflection;
|
||||||
|
|
||||||
|
namespace Content.Server.RandomAppearance;
|
||||||
|
|
||||||
|
public class RandomAppearanceSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<RandomAppearanceComponent, ComponentInit>(OnComponentInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnComponentInit(EntityUid uid, RandomAppearanceComponent component, ComponentInit args)
|
||||||
|
{
|
||||||
|
if (TryComp(uid, out AppearanceComponent? appearance) && component.EnumKey != null)
|
||||||
|
{
|
||||||
|
appearance.SetData(component.EnumKey, _random.Pick(component.SpriteStates));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,7 +49,9 @@
|
|||||||
- type: MovementSpeedModifier
|
- type: MovementSpeedModifier
|
||||||
baseWalkSpeed : 7
|
baseWalkSpeed : 7
|
||||||
baseSprintSpeed : 7
|
baseSprintSpeed : 7
|
||||||
- type: AsteroidRock
|
- type: RandomAppearance
|
||||||
|
# relic
|
||||||
|
key: enum.AsteroidRockVisuals.State
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
drawdepth: Mobs
|
drawdepth: Mobs
|
||||||
layers:
|
layers:
|
||||||
|
|||||||
@@ -8,12 +8,17 @@
|
|||||||
sprite: Objects/Weapons/Melee/pickaxe.rsi
|
sprite: Objects/Weapons/Melee/pickaxe.rsi
|
||||||
state: pickaxe
|
state: pickaxe
|
||||||
- type: Pickaxe
|
- type: Pickaxe
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Piercing: 25
|
||||||
- type: ItemCooldown
|
- type: ItemCooldown
|
||||||
- type: MeleeWeapon
|
- type: MeleeWeapon
|
||||||
damage:
|
damage:
|
||||||
types:
|
types:
|
||||||
Piercing: 10
|
Piercing: 10
|
||||||
Blunt: 4
|
Blunt: 4
|
||||||
|
arcCooldownTime: 3
|
||||||
|
|
||||||
- type: Item
|
- type: Item
|
||||||
size: 24
|
size: 24
|
||||||
sprite: Objects/Weapons/Melee/pickaxe.rsi
|
sprite: Objects/Weapons/Melee/pickaxe.rsi
|
||||||
|
|||||||
@@ -4,14 +4,14 @@
|
|||||||
name: asteroid rock
|
name: asteroid rock
|
||||||
description: That's an asteroid
|
description: That's an asteroid
|
||||||
components:
|
components:
|
||||||
- type: AsteroidRock
|
- type: RandomAppearance
|
||||||
- type: InteractionOutline
|
key: enum.AsteroidRockVisuals.State
|
||||||
|
- type: Mineable
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Structures/Walls/asteroid_rock.rsi
|
sprite: Structures/Walls/asteroid_rock.rsi
|
||||||
state: 0
|
state: 0
|
||||||
- type: Damageable
|
- type: Damageable
|
||||||
damageContainer: Inorganic
|
damageContainer: Inorganic
|
||||||
damageModifierSet: Metallic
|
|
||||||
- type: Destructible
|
- type: Destructible
|
||||||
thresholds:
|
thresholds:
|
||||||
- trigger:
|
- trigger:
|
||||||
|
|||||||
Reference in New Issue
Block a user