Files
riversong-code-showcase/Source/Riversong/Game/World/EntityIdMap/EntityIdMapUpdateSystem.cs
2026-05-21 16:04:49 +02:00

99 lines
3.7 KiB
C#

using System;
using Cysharp.Threading.Tasks;
using UnityEngine.Pool;
namespace DanieleMarotta.RiversongCodeShowcase
{
public class EntityIdMapUpdateSystem : GameSystem, IInitializable, IDisposable, IOnWorldGenerationCompletedCallback
{
[InjectService]
private IEntityCollection _entityCollection;
[InjectService]
private ISignalBus _signalBus;
[InjectService]
private World _world;
[InjectService]
private GameConfig _config;
public EntityIdMapUpdateSystem(IServiceLocator serviceLocator) : base(serviceLocator)
{
}
public UniTask InitializeAsync()
{
_entityCollection.On<ConstructionSite>().Added += OnConstructionSiteAdded;
_entityCollection.On<ConstructionSite>().Removed += OnConstructionSiteRemoved;
_entityCollection.On<Building>().Added += OnBuildingAdded;
_entityCollection.On<Building>().Removed += OnBuildingRemoved;
_signalBus.Subscribe<WorldGenerationCompletedSignal>(OnWorldGenerationCompleted);
_signalBus.Subscribe<RawResourcesRemovedSignal>(OnRawResourcesRemoved);
return UniTask.CompletedTask;
}
public void Dispose()
{
_entityCollection.On<ConstructionSite>().Added -= OnConstructionSiteAdded;
_entityCollection.On<ConstructionSite>().Removed -= OnConstructionSiteRemoved;
_entityCollection.On<Building>().Added -= OnBuildingAdded;
_entityCollection.On<Building>().Removed -= OnBuildingRemoved;
_signalBus.Unsubscribe<WorldGenerationCompletedSignal>(OnWorldGenerationCompleted);
_signalBus.Unsubscribe<RawResourcesRemovedSignal>(OnRawResourcesRemoved);
}
private void OnConstructionSiteAdded(ConstructionSite constructionSite)
{
_world.EntityIdMap.SetBuildingId(constructionSite.Rect, constructionSite.Id);
}
private void OnConstructionSiteRemoved(ConstructionSite constructionSite)
{
_world.EntityIdMap.SetBuildingId(constructionSite.Rect, Entity.InvalidId);
}
private void OnBuildingAdded(Building building)
{
_world.EntityIdMap.SetBuildingId(building.Rect, building.Id);
}
private void OnBuildingRemoved(Building building)
{
_world.EntityIdMap.SetBuildingId(building.Rect, Entity.InvalidId);
}
private void OnWorldGenerationCompleted(WorldGenerationCompletedSignal signal)
{
signal.Callbacks.Add(this);
}
public UniTask OnWorldGenerationCompletedAsync(World world)
{
foreach (var resourceNode in _world.RawResources) _world.EntityIdMap.SetResourceNodeId(resourceNode.Tile, resourceNode.DefinitionId);
return UniTask.CompletedTask;
}
private void OnRawResourcesRemoved(RawResourcesRemovedSignal signal)
{
using var resourceNodesScope = ListPool<(int, bool)>.Get(out var resourceNodes);
foreach (var removedResourceNode in signal.ResourceNodes)
{
resourceNodes.Clear();
_world.RawResources.GetResourceNodes(TileRect.OneTile(removedResourceNode.Tile), _config.GeneralSettings.BaseElevation, resourceNodes);
var definitionId = Entity.InvalidId;
if (resourceNodes.Count > 0)
{
var (resourceId, _) = resourceNodes[0];
_world.RawResources.TryGetResourceNode(resourceId, out var resourceNode);
definitionId = resourceNode.DefinitionId;
}
_world.EntityIdMap.SetResourceNodeId(removedResourceNode.Tile, definitionId);
}
}
}
}