Meteors now leave behind a bit of ore (#30419)
* Meteors that leave behind asteroid ore * bigger offset * Bit more generic * Better defaults * hrm? * I HATE CUSTOM SERIALIZERS * More comments * renamed a variable --------- Co-authored-by: plykiya <plykiya@protonmail.com>
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
using System.Numerics;
|
||||
using Content.Server.Spawners.Components;
|
||||
using Content.Server.Spawners.EntitySystems;
|
||||
using Content.Shared.Random;
|
||||
using Content.Shared.Random.Helpers;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
using Robust.Shared.Spawners;
|
||||
|
||||
namespace Content.Server.Destructible.Thresholds.Behaviors;
|
||||
|
||||
/// <summary>
|
||||
/// Behavior that can be assigned to a trigger that that takes a <see cref="WeightedRandomEntityPrototype"/>
|
||||
/// and spawns a number of the same entity between a given min and max
|
||||
/// at a random offset from the final position of the entity.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataDefinition]
|
||||
public sealed partial class WeightedSpawnEntityBehavior : IThresholdBehavior
|
||||
{
|
||||
/// <summary>
|
||||
/// A table of entities with assigned weights to randomly pick from
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public ProtoId<WeightedRandomEntityPrototype> WeightedEntityTable;
|
||||
|
||||
/// <summary>
|
||||
/// How far away to spawn the entity from the parent position
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float SpawnOffset = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The mininum number of entities to spawn randomly
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int MinSpawn = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The max number of entities to spawn randomly
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int MaxSpawn = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Time in seconds to wait before spawning entities
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float SpawnAfter;
|
||||
|
||||
public void Execute(EntityUid uid, DestructibleSystem system, EntityUid? cause = null)
|
||||
{
|
||||
// Get the position at which to start initially spawning entities
|
||||
var transform = system.EntityManager.System<TransformSystem>();
|
||||
var position = transform.GetMapCoordinates(uid);
|
||||
// Helper function used to randomly get an offset to apply to the original position
|
||||
Vector2 GetRandomVector() => new (system.Random.NextFloat(-SpawnOffset, SpawnOffset), system.Random.NextFloat(-SpawnOffset, SpawnOffset));
|
||||
// Randomly pick the entity to spawn and randomly pick how many to spawn
|
||||
var entity = system.PrototypeManager.Index(WeightedEntityTable).Pick(system.Random);
|
||||
var amountToSpawn = system.Random.NextFloat(MinSpawn, MaxSpawn);
|
||||
|
||||
// Different behaviors for delayed spawning and immediate spawning
|
||||
if (SpawnAfter != 0)
|
||||
{
|
||||
// if it fails to get the spawner, this won't ever work so just return
|
||||
if (!system.PrototypeManager.TryIndex("TemporaryEntityForTimedDespawnSpawners", out var tempSpawnerProto))
|
||||
return;
|
||||
|
||||
// spawn the spawner, assign it a lifetime, and assign the entity that it will spawn when despawned
|
||||
for (var i = 0; i < amountToSpawn; i++)
|
||||
{
|
||||
var spawner = system.EntityManager.SpawnEntity(tempSpawnerProto.ID, position.Offset(GetRandomVector()));
|
||||
system.EntityManager.EnsureComponent<TimedDespawnComponent>(spawner, out var timedDespawnComponent);
|
||||
timedDespawnComponent.Lifetime = SpawnAfter;
|
||||
system.EntityManager.EnsureComponent<SpawnOnDespawnComponent>(spawner, out var spawnOnDespawnComponent);
|
||||
system.EntityManager.System<SpawnOnDespawnSystem>().SetPrototype((spawner, spawnOnDespawnComponent), entity);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// directly spawn the desired entities
|
||||
for (var i = 0; i < amountToSpawn; i++)
|
||||
{
|
||||
system.EntityManager.SpawnEntity(entity, position.Offset(GetRandomVector()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Server.Spawners.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Spawners;
|
||||
|
||||
namespace Content.Server.Spawners.EntitySystems;
|
||||
@@ -19,4 +20,9 @@ public sealed class SpawnOnDespawnSystem : EntitySystem
|
||||
|
||||
Spawn(comp.Prototype, xform.Coordinates);
|
||||
}
|
||||
|
||||
public void SetPrototype(Entity<SpawnOnDespawnComponent> entity, EntProtoId prototype)
|
||||
{
|
||||
entity.Comp.Prototype = prototype;
|
||||
}
|
||||
}
|
||||
|
||||
11
Resources/Prototypes/Entities/Markers/Spawners/temp.yml
Normal file
11
Resources/Prototypes/Entities/Markers/Spawners/temp.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
- type: entity
|
||||
id: TemporaryEntityForTimedDespawnSpawners
|
||||
categories: [ HideSpawnMenu, Spawner ]
|
||||
components:
|
||||
- type: Transform
|
||||
anchored: True
|
||||
- type: Physics
|
||||
bodyType: Static
|
||||
canCollide: false
|
||||
- type: TimedDespawn
|
||||
# we can't declare the SpawnOnDespawnComponent because the entity is required on yml
|
||||
@@ -112,6 +112,11 @@
|
||||
sound:
|
||||
collection: MetalBreak
|
||||
- !type:ExplodeBehavior
|
||||
- !type:WeightedSpawnEntityBehavior
|
||||
weightedEntityTable: "MeteorSpawnAsteroidWallTable"
|
||||
minSpawn: 2
|
||||
maxSpawn: 4
|
||||
spawnAfter: 0.5
|
||||
|
||||
- type: entity
|
||||
parent: BaseMeteor
|
||||
@@ -147,6 +152,12 @@
|
||||
sound:
|
||||
collection: MetalBreak
|
||||
- !type:ExplodeBehavior
|
||||
- !type:WeightedSpawnEntityBehavior
|
||||
weightedEntityTable: "MeteorSpawnAsteroidWallTable"
|
||||
spawnOffset: 2
|
||||
minSpawn: 3
|
||||
maxSpawn: 6
|
||||
spawnAfter: 0.5
|
||||
|
||||
- type: entity
|
||||
parent: BaseMeteor
|
||||
@@ -169,6 +180,12 @@
|
||||
sound:
|
||||
collection: MetalBreak
|
||||
- !type:ExplodeBehavior
|
||||
- !type:WeightedSpawnEntityBehavior
|
||||
weightedEntityTable: "MeteorSpawnAsteroidWallTable"
|
||||
spawnOffset: 3
|
||||
minSpawn: 5
|
||||
maxSpawn: 8
|
||||
spawnAfter: 0.5
|
||||
|
||||
- type: entity
|
||||
parent: BaseMeteor
|
||||
@@ -203,4 +220,4 @@
|
||||
volume: 10
|
||||
- !type:SpillBehavior
|
||||
solution: blood
|
||||
- !type:ExplodeBehavior
|
||||
- !type:ExplodeBehavior
|
||||
@@ -17,6 +17,20 @@
|
||||
GameRuleMeteorSwarmLarge: 5
|
||||
GameRuleUristSwarm: 0.05
|
||||
|
||||
- type: weightedRandomEntity
|
||||
id: MeteorSpawnAsteroidWallTable
|
||||
weights:
|
||||
AsteroidRock: 10
|
||||
AsteroidRockCoal: 5
|
||||
AsteroidRockQuartz: 5
|
||||
AsteroidRockTin: 5
|
||||
AsteroidRockSilver: 2
|
||||
AsteroidRockGold: 2
|
||||
AsteroidRockPlasma: 2
|
||||
AsteroidRockDiamond: 2
|
||||
AsteroidRockUranium: 0.5
|
||||
AsteroidRockBananium: 0.5
|
||||
|
||||
- type: entity
|
||||
parent: BaseGameRule
|
||||
id: GameRuleMeteorSwarm
|
||||
|
||||
Reference in New Issue
Block a user