riversong code showcase

This commit is contained in:
Daniele Marotta
2026-05-21 15:52:18 +02:00
commit 4c9eea1c02
462 changed files with 23406 additions and 0 deletions

View File

@@ -0,0 +1,191 @@
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Pool;
namespace DanieleMarotta.RiversongCodeShowcase
{
[UpdateAfter(typeof(EditingStateGameSystem))]
public class GameObjectsHighlightingSystem : GameSystem, IInitializable, IDisposable
{
[InjectService]
private GameConfig _gameConfig;
[InjectService]
private ISignalBus _signalBus;
[InjectService]
private EditingState _editingState;
[InjectService]
private UIState _uiState;
[InjectService]
private ITileSpace _tileSpace;
[InjectService]
private IEntityCache _entityCache;
[InjectService]
private IBuildingSpatialQuery _buildingSpatialQuery;
[InjectService]
private IProductStackVisualizationCollection _productStackVisualizationCollection;
[InjectService]
private IRawResourceVisualizationCollection _rawResourceVisualizationCollection;
[InjectService]
private IAgentVisualizationCollection _agentVisualizationCollection;
[InjectService]
private IBuildingVisualizationCollection _buildingVisualizationCollection;
[InjectService]
private World _world;
public GameObjectsHighlightingSystem(IServiceLocator serviceLocator) : base(serviceLocator)
{
}
public UniTask InitializeAsync()
{
_signalBus.Subscribe<CollectHighlightedGameObjectsSignal>(OnCollectHighlightedGameObjects);
return UniTask.CompletedTask;
}
public void Dispose()
{
_signalBus.Unsubscribe<CollectHighlightedGameObjectsSignal>(OnCollectHighlightedGameObjects);
}
private bool TryGetSourceBuilding(out BuildingDefinition building, out TileRect sourceRect)
{
var tool = _editingState.ActiveTool;
if (tool is BuildTool buildTool && buildTool.Preview.IsVisible)
{
building = buildTool.Building;
sourceRect = buildTool.BuildingRect;
return true;
}
var selectedBuilding = _uiState.SelectedBuilding;
if (selectedBuilding != null)
{
building = selectedBuilding.Definition;
sourceRect = selectedBuilding.Rect;
return true;
}
building = null;
sourceRect = TileRect.Empty;
return false;
}
private void OnCollectHighlightedGameObjects(CollectHighlightedGameObjectsSignal signal)
{
if (!TryGetSourceBuilding(out var building, out var sourceRect)) return;
CollectBuildings(signal.GameObjects, building, sourceRect);
CollectProductStacks(signal.GameObjects, building, sourceRect);
CollectResources(signal.GameObjects, building, sourceRect);
CollectCritters(signal.GameObjects, building, sourceRect);
}
private void CollectBuildings(List<GameObject> gameObjects, BuildingDefinition sourceBuilding, TileRect sourceRect)
{
if (sourceBuilding.ProvidedProducts.Count > 0)
{
foreach (var house in _entityCache.GetHouses())
{
if (TileMath.StepCount(sourceRect, house.Rect) > sourceBuilding.Range) continue;
AddHighlightedBuilding(gameObjects, house);
}
if (sourceBuilding.FetchesProducts)
foreach (var storage in _entityCache.GetStorageBuildings())
{
if (TileMath.StepCount(sourceRect, storage.Rect) > sourceBuilding.Range) continue;
AddHighlightedBuilding(gameObjects, storage);
}
}
if (sourceBuilding.IsHouse)
{
using var providersScope = ListPool<Building>.Get(out var providers);
_buildingSpatialQuery.FindProvidersForHouse(sourceRect, providers);
foreach (var provider in providers) AddHighlightedBuilding(gameObjects, provider);
}
if (sourceBuilding.IsStorage)
{
using var providersScope = ListPool<Building>.Get(out var providers);
_buildingSpatialQuery.FindProvidersForStorage(sourceRect, providers);
foreach (var provider in providers) AddHighlightedBuilding(gameObjects, provider);
}
}
private void AddHighlightedBuilding(List<GameObject> gameObjects, Building building)
{
if (_buildingVisualizationCollection.TryGetVisualization(building.Id, out var visualization)) gameObjects.Add(visualization.gameObject);
}
private void CollectProductStacks(List<GameObject> gameObjects, BuildingDefinition sourceBuilding, TileRect sourceRect)
{
if (!sourceBuilding.IsStorage) return;
var rangeRect = sourceRect.Inflate(sourceBuilding.Range);
using var productStacksScope = ListPool<ProductStack>.Get(out var productStacks);
_world.ProductStacks.Find(rangeRect, productStacks);
foreach (var productStack in productStacks)
{
if (!_productStackVisualizationCollection.TryGetVisualization(productStack.Id, out var visualization)) continue;
gameObjects.Add(visualization);
}
}
private void CollectResources(List<GameObject> gameObjects, BuildingDefinition sourceBuilding, TileRect sourceRect)
{
if (!sourceBuilding.HarvestedResource) return;
var rangeRect = sourceRect.Inflate(sourceBuilding.Range);
using var resourceIdsScope = ListPool<(int, bool)>.Get(out var resourceIds);
_world.RawResources.GetResourceNodes(rangeRect, _gameConfig.GeneralSettings.BaseElevation, resourceIds);
foreach (var (id, _) in resourceIds)
{
_world.RawResources.TryGetResourceNode(id, out var resourceNode);
if (resourceNode.DefinitionId != sourceBuilding.HarvestedResource.RuntimeId) continue;
if (!_rawResourceVisualizationCollection.TryGetVisualization(resourceNode.Id, out var visualization)) continue;
gameObjects.Add(visualization);
}
}
private void CollectCritters(List<GameObject> gameObjects, BuildingDefinition sourceBuilding, TileRect sourceRect)
{
if (!sourceBuilding.TargetCritter) return;
var rangeRect = sourceRect.Inflate(sourceBuilding.Range);
foreach (var critter in _entityCache.GetCritterAgents())
{
ref var critterState = ref critter.GetCritterStateRW();
if (critterState.CritterDefinitionId != sourceBuilding.TargetCritter.RuntimeId) continue;
var critterTile = _tileSpace.WorldToTile(critter.Position);
if (!rangeRect.Contains(critterTile)) continue;
if (!_agentVisualizationCollection.TryGetVisualization(critter.Id, out var visualization)) continue;
gameObjects.Add(visualization.gameObject);
}
}
}
}