152 lines
4.6 KiB
C#
152 lines
4.6 KiB
C#
using System;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
using UnityEngine.Pool;
|
|
using IServiceProvider = DanieleMarotta.RiversongCodeShowcase.IServiceProvider;
|
|
|
|
namespace DanieleMarotta.RiversongCodeShowcase
|
|
{
|
|
[RequiresWorldReadyForUpdate]
|
|
public class EditingStateGameSystem : GameSystem, IServiceProvider, IInitializable, IDisposable, IUpdatable, IEditingService
|
|
{
|
|
[InjectService]
|
|
private ICancelAction _cancelAction;
|
|
|
|
[InjectService]
|
|
private WorldRenderingState _renderingState;
|
|
|
|
[InjectService]
|
|
private GameConfig _config;
|
|
|
|
[InjectService]
|
|
private World _world;
|
|
|
|
[InjectService]
|
|
private ISignalBus _signalBus;
|
|
|
|
[InjectService]
|
|
private MaterialReplacementCache _materialReplacementCache;
|
|
|
|
public EditingStateGameSystem(IServiceLocator serviceLocator) : base(serviceLocator)
|
|
{
|
|
}
|
|
|
|
public EditingState EditingState { get; private set; }
|
|
|
|
public event Action<EditTool> ActiveToolChanged;
|
|
|
|
public void RegisterServices(IServiceLocator serviceLocator)
|
|
{
|
|
serviceLocator.RegisterService<IEditingService>(this);
|
|
|
|
EditingState = new EditingState();
|
|
serviceLocator.RegisterService(EditingState);
|
|
}
|
|
|
|
public async UniTask InitializeAsync()
|
|
{
|
|
EditingState.BuildTool = new BuildTool(ServiceLocator);
|
|
EditingState.DeleteTool = new DeleteTool(ServiceLocator);
|
|
EditingState.RoadTool = new RoadTool(ServiceLocator);
|
|
await EditingState.InitializeAsync();
|
|
|
|
_cancelAction.AddHandler(
|
|
(int)CancelActions.CancelEditTool,
|
|
_ =>
|
|
{
|
|
if (EditingState.ActiveTool == null) return false;
|
|
|
|
DeactivateTool();
|
|
|
|
return true;
|
|
});
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
EditingState?.Dispose();
|
|
EditingState = null;
|
|
}
|
|
|
|
public void ActivateTool(EditTool tool)
|
|
{
|
|
EditingState.ActiveTool?.OnDisabled();
|
|
EditingState.ActiveTool = tool;
|
|
EditingState.ActiveTool?.OnEnabled();
|
|
|
|
ActiveToolChanged?.Invoke(EditingState.ActiveTool);
|
|
}
|
|
|
|
public void DeactivateTool()
|
|
{
|
|
ActivateTool(null);
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
UpdateActiveTool();
|
|
UpdateHighlightedGameObjects();
|
|
}
|
|
|
|
private void UpdateActiveTool()
|
|
{
|
|
if (EditingState.ActiveTool == null) return;
|
|
|
|
EditingState.ActiveTool.Update();
|
|
|
|
UpdateAffectedTiles();
|
|
UpdateDeletedGameObjects();
|
|
}
|
|
|
|
private void UpdateAffectedTiles()
|
|
{
|
|
foreach (var (tile, type) in EditingState.ActiveTool.AffectedTiles)
|
|
{
|
|
if (_world.BlockMap.IsBlocked(tile, BlockReason.InvalidElevation)) continue;
|
|
|
|
Color32 color;
|
|
var config = _config.UI.TileHighlight;
|
|
switch (type)
|
|
{
|
|
case TileHighlightType.ValidTile:
|
|
color = config.ValidColor;
|
|
break;
|
|
|
|
case TileHighlightType.InvalidTile:
|
|
color = config.InvalidColor;
|
|
break;
|
|
|
|
case TileHighlightType.DeletePreview:
|
|
color = config.DeletePreviewColor;
|
|
break;
|
|
|
|
default:
|
|
color = Color.magenta;
|
|
break;
|
|
}
|
|
|
|
_renderingState.TileHighlight.AddTile(tile, color);
|
|
}
|
|
}
|
|
|
|
private void UpdateDeletedGameObjects()
|
|
{
|
|
EditingState.ActiveTool.GetDeleteGameObjectsPreviewInfo(out var filter, out var rect);
|
|
if (filter == DeletedGameObjectsFilter.None) return;
|
|
|
|
using var gameObjectsScope = ListPool<GameObject>.Get(out var gameObjects);
|
|
_signalBus.Raise(new CollectDeletedGameObjectsSignal(filter, rect, gameObjects));
|
|
|
|
_materialReplacementCache.ReplaceMaterials(gameObjects, _config.UI.DeletedGameObjectsMaterial);
|
|
}
|
|
|
|
private void UpdateHighlightedGameObjects()
|
|
{
|
|
using var gameObjectsScope = ListPool<GameObject>.Get(out var gameObjects);
|
|
_signalBus.Raise(new CollectHighlightedGameObjectsSignal(gameObjects));
|
|
|
|
_materialReplacementCache.ReplaceMaterials(gameObjects, _config.UI.HighlightedGameObjectsMaterial);
|
|
}
|
|
}
|
|
}
|