riversong code showcase

This commit is contained in:
Daniele Marotta
2026-05-21 15:52:18 +02:00
commit 4c9eea1c02
462 changed files with 23406 additions and 0 deletions

View File

@@ -0,0 +1,125 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using Unity.Mathematics;
using UnityEngine;
using Random = Unity.Mathematics.Random;
namespace DanieleMarotta.RiversongCodeShowcase
{
public class MapDataInitializationOperation : IWorldGeneratorOperation
{
private const int HeightStep = 16;
[InjectService]
private GameConfig _config;
public async UniTask Execute(World world)
{
var mapTexture = await GetRandomMapTextureAsync(world.Seed);
var worldSize = new int2(mapTexture.width, mapTexture.height);
world.Size = worldSize;
world.Heightmap = new WorldHeightmap(worldSize);
world.BlockMap = new BlockMap(worldSize);
world.Fertility = new FertilityMap(worldSize);
world.WaterMap = new WaterMap(worldSize);
world.EntityIdMap = new EntityIdMap(worldSize);
world.RoadNetwork = new RoadNetwork(worldSize);
ApplyMapTexture(world, mapTexture);
await InitializeWaterMapAsync(world);
}
private async UniTask<Texture2D> GetRandomMapTextureAsync(int seed)
{
var config = _config.WorldGen;
var mapIndex = new Random((uint)seed).NextInt(config.MapTextures.Count);
var mapTexture = await config.MapTextures[mapIndex].LoadAssetAsync<Texture2D>();
return mapTexture;
}
private void ApplyMapTexture(World world, Texture2D mapTexture)
{
var mapData = mapTexture.GetPixelData<Color32>(0);
var blockMapData = world.BlockMap.GetNativeArray();
var fertilityData = world.Fertility.GetNativeArray();
for (var tileIndex = 0; tileIndex < mapData.Length; tileIndex++)
{
var color = mapData[tileIndex];
var h = color.r / HeightStep;
world.Heightmap.SetValue(tileIndex, h);
if (h != _config.GeneralSettings.BaseElevation)
{
blockMapData[tileIndex] |= BlockReason.InvalidElevation;
continue;
}
var fertility = (float)color.g / byte.MaxValue;
fertilityData[tileIndex] = new FertilityMapValue
{
CurrentFertility = fertility,
MaxFertility = fertility,
LockId = Entity.InvalidId
};
if (color.b > 0)
{
var stride = world.Size.x;
var tile = new int2(tileIndex % stride, tileIndex / stride);
world.CritterHerdsState.EligibleCenters.Add(tile);
}
}
}
private async UniTask InitializeWaterMapAsync(World world)
{
const int MaxWaterDistance = 3;
var budget = new AsyncBudget(world.Size.x * 8);
var open = new Queue<int2>();
foreach (var tile in TileRange.From(0, world.Size - 1))
{
if (BelowWater(world, tile))
open.Enqueue(tile);
else
world.WaterMap.SetValue(tile, int.MaxValue);
await budget.TickAsync();
}
while (open.Count > 0)
{
var current = open.Dequeue();
var currentDistance = world.WaterMap.GetValue(current);
if (currentDistance >= MaxWaterDistance) continue;
foreach (var direction in DirectionVectors.Directions8)
{
var other = current + direction;
if (!world.Contains(other)) continue;
var distance = BelowWater(world, other) ? 0 : currentDistance + 1;
if (distance >= world.WaterMap.GetValue(other)) continue;
world.WaterMap.SetValue(other, distance);
if (distance < MaxWaterDistance) open.Enqueue(other);
}
await budget.TickAsync();
}
}
private bool BelowWater(World world, int2 tile)
{
return world.Heightmap.GetValue(tile) < _config.GeneralSettings.BaseElevation;
}
}
}