riversong code showcase
This commit is contained in:
118
Source/Riversong/Game/World/Roads/RoadManagerSystem.cs
Normal file
118
Source/Riversong/Game/World/Roads/RoadManagerSystem.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Pool;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
[Service(typeof(IRoadFactory))]
|
||||
public class RoadManagerSystem : GameSystem, IInitializable, IDisposable, IUpdatable, IRoadFactory
|
||||
{
|
||||
[InjectService]
|
||||
protected GameConfig _config;
|
||||
|
||||
[InjectService]
|
||||
private World _world;
|
||||
|
||||
[InjectService]
|
||||
private ISignalBus _signalBus;
|
||||
|
||||
private readonly List<List<int2>> _pendingTiles = new();
|
||||
|
||||
private float _placeTileTimer;
|
||||
|
||||
public RoadManagerSystem(IServiceLocator serviceLocator) : base(serviceLocator)
|
||||
{
|
||||
}
|
||||
|
||||
public UniTask InitializeAsync()
|
||||
{
|
||||
_signalBus.Subscribe<DoDeleteToolSignal>(OnDoDeleteToolSignal);
|
||||
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_signalBus.Unsubscribe<DoDeleteToolSignal>(OnDoDeleteToolSignal);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
PlaceTiles();
|
||||
}
|
||||
|
||||
private void PlaceTiles()
|
||||
{
|
||||
if (_pendingTiles.Count == 0)
|
||||
{
|
||||
_placeTileTimer = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
_placeTileTimer += Time.unscaledDeltaTime;
|
||||
if (_placeTileTimer < _config.Roads.PlaceTileInterval) return;
|
||||
|
||||
for (var i = _pendingTiles.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tileQueue = _pendingTiles[i];
|
||||
while (tileQueue.Count > 0)
|
||||
{
|
||||
var tile = tileQueue[0];
|
||||
tileQueue.RemoveAt(0);
|
||||
if (_world.RoadNetwork.IsRoadTile(tile)) continue;
|
||||
|
||||
_world.RoadNetwork.AddRoadTile(tile);
|
||||
UpdateTilesAround(tile);
|
||||
|
||||
_signalBus.Raise(new RoadTileUpdatedSignal(tile, true));
|
||||
|
||||
_placeTileTimer = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (tileQueue.Count == 0)
|
||||
{
|
||||
_pendingTiles.RemoveAt(i);
|
||||
ListPool<int2>.Release(tileQueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDoDeleteToolSignal(DoDeleteToolSignal signal)
|
||||
{
|
||||
using var deletedTilesScope = ListPool<int2>.Get(out var deletedTiles);
|
||||
|
||||
foreach (var tile in TileRange.From(signal.Rect))
|
||||
{
|
||||
if (!_world.RoadNetwork.IsRoadTile(tile)) continue;
|
||||
|
||||
_world.RoadNetwork.RemoveRoadTile(tile);
|
||||
UpdateTilesAround(tile);
|
||||
|
||||
deletedTiles.Add(tile);
|
||||
}
|
||||
|
||||
foreach (var tile in deletedTiles) _signalBus.Raise(new RoadTileUpdatedSignal(tile, false));
|
||||
}
|
||||
|
||||
private void UpdateTilesAround(int2 tile)
|
||||
{
|
||||
if (tile.x > 0) _world.RoadNetwork.UpdateRoadTile(tile + new int2(-1, 0));
|
||||
if (tile.y < _world.Size.x - 1) _world.RoadNetwork.UpdateRoadTile(tile + new int2(1, 0));
|
||||
if (tile.y > 0) _world.RoadNetwork.UpdateRoadTile(tile + new int2(0, -1));
|
||||
if (tile.y < _world.Size.y - 1) _world.RoadNetwork.UpdateRoadTile(tile + new int2(0, 1));
|
||||
}
|
||||
|
||||
public void CreateRoad(int2 startTile, int2 endTile)
|
||||
{
|
||||
var tileQueue = ListPool<int2>.Get();
|
||||
_pendingTiles.Add(tileQueue);
|
||||
|
||||
TileMath.WalkLine(startTile, endTile, tileQueue.Add);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user