@@ -1,4 +1,6 @@
|
|||||||
|
using Content.Shared.EntityList;
|
||||||
using Content.Shared.Whitelist;
|
using Content.Shared.Whitelist;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Server.Gatherable.Components;
|
namespace Content.Server.Gatherable.Components;
|
||||||
|
|
||||||
@@ -10,7 +12,7 @@ public sealed partial class GatherableComponent : Component
|
|||||||
/// Whitelist for specifying the kind of tools can be used on a resource
|
/// Whitelist for specifying the kind of tools can be used on a resource
|
||||||
/// Supports multiple tags.
|
/// Supports multiple tags.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("whitelist", required: true)]
|
[DataField(required: true)]
|
||||||
public EntityWhitelist? ToolWhitelist;
|
public EntityWhitelist? ToolWhitelist;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -18,14 +20,20 @@ public sealed partial class GatherableComponent : Component
|
|||||||
/// (Tag1, Tag2, LootTableID1, LootTableID2 are placeholders for example)
|
/// (Tag1, Tag2, LootTableID1, LootTableID2 are placeholders for example)
|
||||||
/// --------------------
|
/// --------------------
|
||||||
/// useMappedLoot: true
|
/// useMappedLoot: true
|
||||||
/// whitelist:
|
/// toolWhitelist:
|
||||||
/// tags:
|
/// tags:
|
||||||
/// - Tag1
|
/// - Tag1
|
||||||
/// - Tag2
|
/// - Tag2
|
||||||
/// mappedLoot:
|
/// loot:
|
||||||
/// Tag1: LootTableID1
|
/// Tag1: LootTableID1
|
||||||
/// Tag2: LootTableID2
|
/// Tag2: LootTableID2
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("loot")]
|
[DataField]
|
||||||
public Dictionary<string, string>? MappedLoot = new();
|
public Dictionary<string, ProtoId<EntityLootTablePrototype>>? Loot = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Random shift of the appearing entity during gathering
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public float GatherOffset = 0.3f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using Content.Server.Gatherable.Components;
|
using Content.Server.Gatherable.Components;
|
||||||
using Content.Server.Projectiles;
|
|
||||||
using Content.Shared.Projectiles;
|
using Content.Shared.Projectiles;
|
||||||
using Content.Shared.Weapons.Ranged.Systems;
|
|
||||||
using Robust.Shared.Physics.Events;
|
using Robust.Shared.Physics.Events;
|
||||||
|
|
||||||
namespace Content.Server.Gatherable;
|
namespace Content.Server.Gatherable;
|
||||||
@@ -13,20 +11,20 @@ public sealed partial class GatherableSystem
|
|||||||
SubscribeLocalEvent<GatheringProjectileComponent, StartCollideEvent>(OnProjectileCollide);
|
SubscribeLocalEvent<GatheringProjectileComponent, StartCollideEvent>(OnProjectileCollide);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnProjectileCollide(EntityUid uid, GatheringProjectileComponent component, ref StartCollideEvent args)
|
private void OnProjectileCollide(Entity<GatheringProjectileComponent> gathering, ref StartCollideEvent args)
|
||||||
{
|
{
|
||||||
if (!args.OtherFixture.Hard ||
|
if (!args.OtherFixture.Hard ||
|
||||||
args.OurFixtureId != SharedProjectileSystem.ProjectileFixture ||
|
args.OurFixtureId != SharedProjectileSystem.ProjectileFixture ||
|
||||||
component.Amount <= 0 ||
|
gathering.Comp.Amount <= 0 ||
|
||||||
!TryComp<GatherableComponent>(args.OtherEntity, out var gatherable))
|
!TryComp<GatherableComponent>(args.OtherEntity, out var gatherable))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gather(args.OtherEntity, uid, gatherable);
|
Gather(args.OtherEntity, gathering, gatherable);
|
||||||
component.Amount--;
|
gathering.Comp.Amount--;
|
||||||
|
|
||||||
if (component.Amount <= 0)
|
if (gathering.Comp.Amount <= 0)
|
||||||
QueueDel(uid);
|
QueueDel(gathering);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
using Content.Server.Destructible;
|
using Content.Server.Destructible;
|
||||||
using Content.Server.Gatherable.Components;
|
using Content.Server.Gatherable.Components;
|
||||||
using Content.Shared.EntityList;
|
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Tag;
|
using Content.Shared.Tag;
|
||||||
using Content.Shared.Weapons.Melee.Events;
|
using Content.Shared.Weapons.Melee.Events;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Audio;
|
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
@@ -14,7 +12,7 @@ namespace Content.Server.Gatherable;
|
|||||||
|
|
||||||
public sealed partial class GatherableSystem : EntitySystem
|
public sealed partial class GatherableSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly DestructibleSystem _destructible = default!;
|
[Dependency] private readonly DestructibleSystem _destructible = default!;
|
||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
@@ -30,20 +28,20 @@ public sealed partial class GatherableSystem : EntitySystem
|
|||||||
InitializeProjectile();
|
InitializeProjectile();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAttacked(EntityUid uid, GatherableComponent component, AttackedEvent args)
|
private void OnAttacked(Entity<GatherableComponent> gatherable, ref AttackedEvent args)
|
||||||
{
|
{
|
||||||
if (component.ToolWhitelist?.IsValid(args.Used, EntityManager) != true)
|
if (gatherable.Comp.ToolWhitelist?.IsValid(args.Used, EntityManager) != true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Gather(uid, args.User, component);
|
Gather(gatherable, args.User);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnActivate(EntityUid uid, GatherableComponent component, ActivateInWorldEvent args)
|
private void OnActivate(Entity<GatherableComponent> gatherable, ref ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (component.ToolWhitelist?.IsValid(args.User, EntityManager) != true)
|
if (gatherable.Comp.ToolWhitelist?.IsValid(args.User, EntityManager) != true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Gather(uid, args.User, component);
|
Gather(gatherable, args.User);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Gather(EntityUid gatheredUid, EntityUid? gatherer = null, GatherableComponent? component = null)
|
public void Gather(EntityUid gatheredUid, EntityUid? gatherer = null, GatherableComponent? component = null)
|
||||||
@@ -60,25 +58,22 @@ public sealed partial class GatherableSystem : EntitySystem
|
|||||||
_destructible.DestroyEntity(gatheredUid);
|
_destructible.DestroyEntity(gatheredUid);
|
||||||
|
|
||||||
// Spawn the loot!
|
// Spawn the loot!
|
||||||
if (component.MappedLoot == null)
|
if (component.Loot == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var pos = _transform.GetMapCoordinates(gatheredUid);
|
var pos = _transform.GetMapCoordinates(gatheredUid);
|
||||||
|
|
||||||
foreach (var (tag, table) in component.MappedLoot)
|
foreach (var (tag, table) in component.Loot)
|
||||||
{
|
{
|
||||||
if (tag != "All")
|
if (tag != "All")
|
||||||
{
|
{
|
||||||
if (gatherer != null && !_tagSystem.HasTag(gatherer.Value, tag))
|
if (gatherer != null && !_tagSystem.HasTag(gatherer.Value, tag))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var getLoot = _prototypeManager.Index<EntityLootTablePrototype>(table);
|
var getLoot = _proto.Index(table);
|
||||||
var spawnLoot = getLoot.GetSpawns(_random);
|
var spawnLoot = getLoot.GetSpawns(_random);
|
||||||
var spawnPos = pos.Offset(_random.NextVector2(0.3f));
|
var spawnPos = pos.Offset(_random.NextVector2(component.GatherOffset));
|
||||||
Spawn(spawnLoot[0], spawnPos);
|
Spawn(spawnLoot[0], spawnPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,14 +19,12 @@
|
|||||||
!type:PhysShapeCircle
|
!type:PhysShapeCircle
|
||||||
radius: 0.2
|
radius: 0.2
|
||||||
- type: InteractionOutline
|
- type: InteractionOutline
|
||||||
# TODO: Nuke this shit
|
|
||||||
- type: OreVein
|
|
||||||
oreChance: 1.0
|
|
||||||
currentOre: SpaceShrooms
|
|
||||||
- type: Gatherable
|
- type: Gatherable
|
||||||
whitelist:
|
toolWhitelist:
|
||||||
components:
|
components:
|
||||||
- Hands
|
- Hands
|
||||||
|
loot:
|
||||||
|
All: SpaceshroomGather
|
||||||
- type: Damageable
|
- type: Damageable
|
||||||
damageContainer: Inorganic
|
damageContainer: Inorganic
|
||||||
damageModifierSet: Wood
|
damageModifierSet: Wood
|
||||||
@@ -39,6 +37,13 @@
|
|||||||
- !type:DoActsBehavior
|
- !type:DoActsBehavior
|
||||||
acts: [ "Destruction" ]
|
acts: [ "Destruction" ]
|
||||||
|
|
||||||
|
- type: entityLootTable
|
||||||
|
id: SpaceshroomGather
|
||||||
|
entries:
|
||||||
|
- id: FoodSpaceshroom
|
||||||
|
amount: 1
|
||||||
|
maxAmount: 1
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: spaceshroom
|
name: spaceshroom
|
||||||
parent: FoodProduceBase
|
parent: FoodProduceBase
|
||||||
|
|||||||
@@ -375,7 +375,7 @@
|
|||||||
noRot: true
|
noRot: true
|
||||||
- type: SoundOnGather
|
- type: SoundOnGather
|
||||||
- type: Gatherable
|
- type: Gatherable
|
||||||
whitelist:
|
toolWhitelist:
|
||||||
tags:
|
tags:
|
||||||
- Pickaxe
|
- Pickaxe
|
||||||
- type: Damageable
|
- type: Damageable
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
# TODO: Kill ore veins
|
# TODO: Kill ore veins
|
||||||
# Split it into 2 components, 1 for "spawn XYZ on destruction" and 1 for "randomly select one of these for spawn on destruction"
|
# Split it into 2 components, 1 for "spawn XYZ on destruction" and 1 for "randomly select one of these for spawn on destruction"
|
||||||
# You could even just use an entityspawncollection instead.
|
|
||||||
- type: ore
|
|
||||||
id: SpaceShrooms
|
|
||||||
oreEntity: FoodSpaceshroom
|
|
||||||
|
|
||||||
# High yields
|
# High yields
|
||||||
- type: ore
|
- type: ore
|
||||||
|
|||||||
Reference in New Issue
Block a user