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",
|
||||
"Healing",
|
||||
"Material",
|
||||
"RandomAppearance",
|
||||
"Mineable",
|
||||
"RangedMagazine",
|
||||
"Ammo",
|
||||
"AiController",
|
||||
"Computer",
|
||||
"AsteroidRock",
|
||||
"ResearchServer",
|
||||
"ResearchPointSource",
|
||||
"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 Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Content.Server.Mining.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
[RegisterComponent, ComponentProtoName("Pickaxe")]
|
||||
public class PickaxeComponent : Component
|
||||
{
|
||||
public override string Name => "Pickaxe";
|
||||
|
||||
[DataField("miningSound")]
|
||||
[DataField("sound")]
|
||||
public SoundSpecifier MiningSound { get; set; } = new SoundPathSpecifier("/Audio/Items/Mining/pickaxe.ogg");
|
||||
|
||||
[DataField("miningSpeedMultiplier")]
|
||||
public float MiningSpeedMultiplier { get; set; } = 1f;
|
||||
[DataField("timeMultiplier")]
|
||||
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
|
||||
baseWalkSpeed : 7
|
||||
baseSprintSpeed : 7
|
||||
- type: AsteroidRock
|
||||
- type: RandomAppearance
|
||||
# relic
|
||||
key: enum.AsteroidRockVisuals.State
|
||||
- type: Sprite
|
||||
drawdepth: Mobs
|
||||
layers:
|
||||
|
||||
@@ -8,12 +8,17 @@
|
||||
sprite: Objects/Weapons/Melee/pickaxe.rsi
|
||||
state: pickaxe
|
||||
- type: Pickaxe
|
||||
damage:
|
||||
types:
|
||||
Piercing: 25
|
||||
- type: ItemCooldown
|
||||
- type: MeleeWeapon
|
||||
damage:
|
||||
types:
|
||||
Piercing: 10
|
||||
Blunt: 4
|
||||
arcCooldownTime: 3
|
||||
|
||||
- type: Item
|
||||
size: 24
|
||||
sprite: Objects/Weapons/Melee/pickaxe.rsi
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
name: asteroid rock
|
||||
description: That's an asteroid
|
||||
components:
|
||||
- type: AsteroidRock
|
||||
- type: InteractionOutline
|
||||
- type: RandomAppearance
|
||||
key: enum.AsteroidRockVisuals.State
|
||||
- type: Mineable
|
||||
- type: Sprite
|
||||
sprite: Structures/Walls/asteroid_rock.rsi
|
||||
state: 0
|
||||
- type: Damageable
|
||||
damageContainer: Inorganic
|
||||
damageModifierSet: Metallic
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
|
||||
Reference in New Issue
Block a user