riversong code showcase
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Pool;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
[GameSystemGroup(typeof(EarlyAgentsSystemGroup))]
|
||||
public class CritterSpawnSystem : GameSystem, IUpdatable
|
||||
{
|
||||
[InjectService]
|
||||
private World _world;
|
||||
|
||||
[InjectService]
|
||||
private IEntityCollection _entityCollection;
|
||||
|
||||
[InjectService]
|
||||
private IAgentFactory _agentFactory;
|
||||
|
||||
[InjectService]
|
||||
private ITileSpace _tileSpace;
|
||||
|
||||
public CritterSpawnSystem(IServiceLocator serviceLocator) : base(serviceLocator)
|
||||
{
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
foreach (CritterHerd herd in _entityCollection.GetInternalEntityList(typeof(CritterHerd)))
|
||||
{
|
||||
ref var agentSourceState = ref herd.GetAgentSourceStateRW();
|
||||
|
||||
if (agentSourceState.AgentCount[(int)AgentJob.None] >= herd.MaxCritterCount)
|
||||
{
|
||||
herd.SpawnTimer = float.MinValue;
|
||||
continue;
|
||||
}
|
||||
|
||||
var critterDefinition = herd.CritterDefinition;
|
||||
|
||||
if (herd.SpawnTimer < 0) herd.SpawnTimer = Random.Range(critterDefinition.MinSpawningInterval, critterDefinition.MaxSpawningInterval);
|
||||
|
||||
herd.SpawnTimer -= Time.deltaTime;
|
||||
if (herd.SpawnTimer <= 0)
|
||||
{
|
||||
herd.SpawnTimer = float.MinValue;
|
||||
|
||||
var wanderingRadius = critterDefinition.AgentDefinition.WanderingRadius;
|
||||
if (!TryFindRandomFreeTile(herd.Center - wanderingRadius, herd.Center + wanderingRadius, out var tile)) continue;
|
||||
|
||||
var position = _tileSpace.TileToWorld(tile);
|
||||
var critter = _agentFactory.CreateCritter(critterDefinition, herd, position);
|
||||
critter.WanderingCenter = tile;
|
||||
|
||||
ref var intentQueue = ref critter.GetIntentQueueRW();
|
||||
intentQueue.EnqueueIntent(AgentIntent.MakeLive());
|
||||
IntentQueue.LoopWandering(ref intentQueue, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryFindRandomFreeTile(int2 min, int2 max, out int2 tile)
|
||||
{
|
||||
using var candidatesScope = ListPool<int2>.Get(out var candidates);
|
||||
|
||||
foreach (var candidate in TileRange.From(min, max))
|
||||
if (!_world.BlockMap.IsBlocked(candidate, BlockReason.BlocksAgents))
|
||||
candidates.Add(candidate);
|
||||
|
||||
if (candidates.Count == 0)
|
||||
{
|
||||
tile = int2.zero;
|
||||
return false;
|
||||
}
|
||||
|
||||
tile = candidates[Random.Range(0, candidates.Count)];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user