110 lines
3.5 KiB
C#
110 lines
3.5 KiB
C#
using Cysharp.Threading.Tasks;
|
|
|
|
namespace DanieleMarotta.RiversongCodeShowcase
|
|
{
|
|
[UpdateAfter(typeof(EditingStateGameSystem))]
|
|
public class BuildingSelectionSystem : GameSystem, IInitializable, IUpdatable
|
|
{
|
|
[InjectService]
|
|
private GameConfig _gameConfig;
|
|
|
|
[InjectService]
|
|
private IPointerService _pointerService;
|
|
|
|
[InjectService]
|
|
private UIState _uiState;
|
|
|
|
[InjectService]
|
|
private ITileSpace _tileSpace;
|
|
|
|
[InjectService]
|
|
private IEntityCollection _entityCollection;
|
|
|
|
[InjectService]
|
|
private ICancelAction _cancelAction;
|
|
|
|
[InjectService]
|
|
private EditingState _editingState;
|
|
|
|
[InjectService]
|
|
private ISignalBus _signalBus;
|
|
|
|
[InjectService]
|
|
private IBuildingVisualizationCollection _buildingVisualizationCollection;
|
|
|
|
[InjectService]
|
|
private World _world;
|
|
|
|
[InjectService]
|
|
private MaterialReplacementCache _materialReplacementCache;
|
|
|
|
public BuildingSelectionSystem(IServiceLocator serviceLocator) : base(serviceLocator)
|
|
{
|
|
}
|
|
|
|
public UniTask InitializeAsync()
|
|
{
|
|
_cancelAction.AddHandler(
|
|
(int)CancelActions.CancelSelection,
|
|
_ =>
|
|
{
|
|
if (_uiState.SelectedBuilding == null) return false;
|
|
SetSelectedBuilding(null);
|
|
return true;
|
|
});
|
|
|
|
return UniTask.CompletedTask;
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
if (_uiState.SelectedBuilding != null && !_entityCollection.Exists(_uiState.SelectedBuilding.Id))
|
|
{
|
|
SetSelectedBuilding(null);
|
|
return;
|
|
}
|
|
|
|
if (_editingState.ActiveTool != null)
|
|
{
|
|
SetSelectedBuilding(null);
|
|
return;
|
|
}
|
|
|
|
var buildingUnderPointer = GetBuildingUnderPointer();
|
|
if (_pointerService.TryConsumeLeftClick()) SetSelectedBuilding(buildingUnderPointer);
|
|
|
|
HighlightBuilding(buildingUnderPointer);
|
|
HighlightBuilding(_uiState.SelectedBuilding);
|
|
}
|
|
|
|
private Building GetBuildingUnderPointer()
|
|
{
|
|
if (_pointerService.IsPointerOverUI) return null;
|
|
if (!_pointerService.TryGetPositionOnTerrain(out var position)) return null;
|
|
|
|
var tile = _tileSpace.WorldToTile(position);
|
|
ref var entityIdMapValue = ref _world.EntityIdMap.GetValueRW(tile);
|
|
if (entityIdMapValue.BuildingId == Entity.InvalidId) return null;
|
|
|
|
return _entityCollection.TryGet<Building>(entityIdMapValue.BuildingId, out var building) ? building : null;
|
|
}
|
|
|
|
private void HighlightBuilding(Building building)
|
|
{
|
|
if (building == null) return;
|
|
if (!_buildingVisualizationCollection.TryGetVisualization(building.Id, out var visualization)) return;
|
|
|
|
_materialReplacementCache.ReplaceMaterials(visualization.gameObject, _gameConfig.UI.HighlightedGameObjectsMaterial);
|
|
}
|
|
|
|
private void SetSelectedBuilding(Building selectedBuilding)
|
|
{
|
|
if (_uiState.SelectedBuilding == selectedBuilding) return;
|
|
|
|
var oldSelection = _uiState.SelectedBuilding;
|
|
_uiState.SelectedBuilding = selectedBuilding;
|
|
|
|
_signalBus.Raise(new SelectedBuildingChangedSignal(oldSelection, _uiState.SelectedBuilding));
|
|
}
|
|
}
|
|
} |