riversong code showcase
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using Random = Unity.Mathematics.Random;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public class TreeResourcesGeneratorOperation : IWorldGeneratorOperation
|
||||
{
|
||||
[InjectService]
|
||||
private GameConfig _config;
|
||||
|
||||
[InjectService]
|
||||
private ITileSpace _tileSpace;
|
||||
|
||||
public async UniTask Execute(World world)
|
||||
{
|
||||
await GenerateTreesAsync(world);
|
||||
}
|
||||
|
||||
private async UniTask GenerateTreesAsync(World world)
|
||||
{
|
||||
var config = _config.WorldGen;
|
||||
var treeDefinition = await config.Trees.TreeDefinition.LoadAssetAsync<ResourceNodeDefinition>();
|
||||
|
||||
var horizontalResolution = Mathf.FloorToInt(world.Size.x / config.Trees.Spacing);
|
||||
var verticalResolution = Mathf.FloorToInt(world.Size.y / config.Trees.Spacing);
|
||||
|
||||
var random = new Random((uint)world.Seed);
|
||||
var noiseSalt = world.Seed % ushort.MaxValue * 37;
|
||||
|
||||
for (var x = 0; x < horizontalResolution; x++)
|
||||
for (var z = 0; z < verticalResolution; z++)
|
||||
{
|
||||
var treePosition = new Vector3((x + 0.5f) * config.Trees.Spacing, 0, (z + 0.5f) * config.Trees.Spacing);
|
||||
if (z % 2 == 0) treePosition.x += 0.5f * config.Trees.Spacing;
|
||||
|
||||
treePosition.x += Mathf.Lerp(config.Trees.OffsetRange.x, config.Trees.OffsetRange.y, random.NextFloat());
|
||||
treePosition.z += Mathf.Lerp(config.Trees.OffsetRange.x, config.Trees.OffsetRange.y, random.NextFloat());
|
||||
|
||||
var tile = _tileSpace.WorldToTile(treePosition);
|
||||
|
||||
if (!EnoughSpaceAround(world, tile)) continue;
|
||||
|
||||
var h = world.Heightmap.GetValue(tile);
|
||||
if (h == 0) continue;
|
||||
|
||||
treePosition.y = h;
|
||||
|
||||
var noiseSamplePos = new float2(h * 997 + x, noiseSalt + z) * config.Trees.NoiseScale;
|
||||
var n = noise.snoise(noiseSamplePos);
|
||||
if (n < 1 - config.Trees.Coverage && random.NextFloat() < 1 - config.Trees.RandomTreeChance) continue;
|
||||
|
||||
world.RawResources.AddResourceNode(
|
||||
new ResourceNode
|
||||
{
|
||||
Id = 1 + world.RawResources.Count,
|
||||
DefinitionId = treeDefinition.RuntimeId,
|
||||
Position = treePosition,
|
||||
Tile = tile,
|
||||
Elevation = _tileSpace.GetElevation(treePosition.y),
|
||||
CanBeDeleted = true
|
||||
});
|
||||
|
||||
world.BlockMap.AddReason(tile, BlockReason.RawResource);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool EnoughSpaceAround(World world, int2 center)
|
||||
{
|
||||
const int radius = 1;
|
||||
|
||||
for (var x = -radius; x <= radius; x++)
|
||||
for (var y = -radius; y <= radius; y++)
|
||||
{
|
||||
var p = center + new int2(x, y);
|
||||
|
||||
if (!world.Contains(p)) continue;
|
||||
|
||||
if (world.Fertility.GetValue(p).MaxFertility > 0) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user