riversong code showcase
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
using System.Collections.Generic;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Unity.Mathematics;
|
||||
using Random = Unity.Mathematics.Random;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public class StoneResourcesGeneratorOperation : IWorldGeneratorOperation
|
||||
{
|
||||
[InjectService]
|
||||
private GameConfig _config;
|
||||
|
||||
[InjectService]
|
||||
private ITileSpace _tileSpace;
|
||||
|
||||
public async UniTask Execute(World world)
|
||||
{
|
||||
return; // Temporarily disabled
|
||||
|
||||
var blockMap = world.BlockMap;
|
||||
var resourcesState = world.RawResources;
|
||||
|
||||
var config = _config.WorldGen.Stone;
|
||||
var stoneDefinition = await config.StoneDefinition.LoadAssetAsync<ResourceNodeDefinition>();
|
||||
|
||||
var random = new Random((uint)world.Seed);
|
||||
var count = random.NextInt(config.Count.x, config.Count.y + 1);
|
||||
|
||||
var candidates = new List<(int2, int2, Directions)>();
|
||||
foreach (var tile in TileRange.From(1, world.Size - 2))
|
||||
if (ValidateCandidate(world, tile, out var side, out var orientation))
|
||||
candidates.Add((tile, side, orientation));
|
||||
|
||||
var current = new List<int2>(count);
|
||||
while (candidates.Count > 0 && current.Count < count)
|
||||
{
|
||||
var i = random.NextInt(candidates.Count);
|
||||
var (tile, side, orientation) = candidates[i];
|
||||
candidates[i] = candidates[^1];
|
||||
candidates.RemoveAt(candidates.Count - 1);
|
||||
|
||||
if (TooCloseToOtherResources(tile, current, config.Spacing)) continue;
|
||||
|
||||
current.Add(tile);
|
||||
|
||||
var position = _tileSpace.TileToWorld(tile);
|
||||
resourcesState.AddResourceNode(
|
||||
new ResourceNode
|
||||
{
|
||||
Id = 1 + resourcesState.Count,
|
||||
DefinitionId = stoneDefinition.RuntimeId,
|
||||
Position = position,
|
||||
Tile = tile,
|
||||
Orientation = orientation,
|
||||
Elevation = _config.GeneralSettings.BaseElevation
|
||||
});
|
||||
|
||||
blockMap.AddReason(tile, BlockReason.RawResource);
|
||||
blockMap.AddReason(tile + side, BlockReason.RawResource);
|
||||
blockMap.AddReason(tile - side, BlockReason.RawResource);
|
||||
}
|
||||
}
|
||||
|
||||
private bool ValidateCandidate(World world, int2 tile, out int2 side, out Directions orientation)
|
||||
{
|
||||
side = default;
|
||||
orientation = default;
|
||||
return world.Heightmap.GetValue(tile) == _config.GeneralSettings.BaseElevation &&
|
||||
!world.BlockMap.IsBlocked(tile) &&
|
||||
NextToCliff(world, tile, out side, out orientation);
|
||||
}
|
||||
|
||||
private bool NextToCliff(World world, int2 tile, out int2 side, out Directions orientation)
|
||||
{
|
||||
side = new int2(0, 1);
|
||||
|
||||
if (NextToCliff(world, tile, new int2(1, 0), side))
|
||||
{
|
||||
orientation = Directions.East;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NextToCliff(world, tile, new int2(-1, 0), side))
|
||||
{
|
||||
orientation = Directions.West;
|
||||
return true;
|
||||
}
|
||||
|
||||
side = new int2(1, 0);
|
||||
|
||||
if (NextToCliff(world, tile, new int2(0, 1), side))
|
||||
{
|
||||
orientation = Directions.North;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NextToCliff(world, tile, new int2(0, -1), side))
|
||||
{
|
||||
orientation = Directions.South;
|
||||
return true;
|
||||
}
|
||||
|
||||
orientation = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool NextToCliff(World world, int2 bottomTile, int2 direction, int2 side)
|
||||
{
|
||||
var topTile = bottomTile + direction;
|
||||
var baseElevation = _config.GeneralSettings.BaseElevation;
|
||||
|
||||
return world.Heightmap.GetValue(bottomTile + side) == baseElevation &&
|
||||
world.Heightmap.GetValue(bottomTile - side) == baseElevation &&
|
||||
world.Heightmap.GetValue(topTile) > baseElevation &&
|
||||
world.Heightmap.GetValue(topTile + side) > baseElevation &&
|
||||
world.Heightmap.GetValue(topTile - side) > baseElevation;
|
||||
}
|
||||
|
||||
private static bool TooCloseToOtherResources(int2 tile, List<int2> alreadyPlaced, int spacing)
|
||||
{
|
||||
foreach (var other in alreadyPlaced)
|
||||
if (TileMath.StepCount(tile, other) < spacing)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user