2022-12-28 16:22:53 +01:00
|
|
|
using System;
|
2023-05-05 16:26:33 +02:00
|
|
|
using System.Diagnostics;
|
2023-11-10 11:11:08 +01:00
|
|
|
using System.Linq;
|
|
|
|
using Godot;
|
2023-06-11 22:04:22 +02:00
|
|
|
using Godot.Collections;
|
2023-07-09 00:16:37 +02:00
|
|
|
using Namespace;
|
2022-12-28 16:22:53 +01:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public class TileWorld : Spatial {
|
2023-11-10 11:11:08 +01:00
|
|
|
// exports
|
|
|
|
[Export] public bool DebugMap;
|
|
|
|
[ExportFlagsEnum(typeof(MapType))] public MapType GenerationMapType = MapType.Debug;
|
|
|
|
[Export] public int Size = 64;
|
|
|
|
|
|
|
|
// constants
|
|
|
|
private static readonly Color RockColor = new(0.5f, 0.5f, 0.4f);
|
|
|
|
private static readonly Color GrassColor = new(0, 0.4f, 0);
|
|
|
|
private PackedScene _chestScene = GD.Load<PackedScene>("res://entities/Chest.tscn");
|
|
|
|
|
|
|
|
private GenerationState _currentGenerationState = GenerationState.Heightmap;
|
|
|
|
private Spatial _environmentNode;
|
|
|
|
private readonly Array<Spatial> _grassAssets = new();
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
private enum GenerationState {
|
2023-05-21 17:24:37 +02:00
|
|
|
Heightmap,
|
|
|
|
Color,
|
2023-06-11 22:04:22 +02:00
|
|
|
Objects,
|
2023-05-21 17:24:37 +02:00
|
|
|
Done
|
|
|
|
}
|
|
|
|
|
2022-12-28 16:22:53 +01:00
|
|
|
// signals
|
|
|
|
[Signal]
|
2023-11-10 11:11:08 +01:00
|
|
|
private delegate void WorldGenerated();
|
2022-12-28 16:22:53 +01:00
|
|
|
|
|
|
|
// public members
|
2023-11-18 22:32:57 +01:00
|
|
|
public enum MapType {
|
2023-07-09 00:16:37 +02:00
|
|
|
Noise,
|
|
|
|
Debug,
|
2023-11-10 11:11:08 +01:00
|
|
|
Flat
|
2023-07-09 00:16:37 +02:00
|
|
|
}
|
|
|
|
|
2023-07-28 22:23:41 +02:00
|
|
|
public Image ColormapImage;
|
2023-06-23 15:39:07 +02:00
|
|
|
public Spatial Entities;
|
2023-11-10 11:11:08 +01:00
|
|
|
public Image HeightmapImage;
|
|
|
|
public float HeightScale = 1.0f;
|
2023-07-16 20:38:39 +02:00
|
|
|
public HexGrid HexGrid;
|
2023-11-10 11:11:08 +01:00
|
|
|
public Image NavigationmapImage;
|
|
|
|
public int Seed = 0;
|
2022-12-28 16:22:53 +01:00
|
|
|
|
|
|
|
// private members
|
2023-07-16 20:38:39 +02:00
|
|
|
private int _halfSize;
|
2023-05-21 17:24:37 +02:00
|
|
|
private TextureRect _heightmapOffscreenTextureRect;
|
2023-11-10 11:11:08 +01:00
|
|
|
private Viewport _heightmapOffscreenViewport;
|
|
|
|
private int _resizeExtraFrameCount;
|
2023-07-28 22:23:41 +02:00
|
|
|
private bool _resizeTriggered;
|
2023-11-10 11:11:08 +01:00
|
|
|
private readonly Array<Spatial> _rockAssets = new();
|
|
|
|
private Random _tileTypeRandom;
|
|
|
|
private readonly Array<Spatial> _treeAssets = new();
|
|
|
|
private TextureRect _worldOffscreenTextureRect;
|
|
|
|
private Viewport _worldOffscreenViewport;
|
2022-12-28 16:22:53 +01:00
|
|
|
|
|
|
|
// Called when the node enters the scene tree for the first time.
|
2023-11-18 22:32:57 +01:00
|
|
|
public override void _Ready() {
|
2023-07-16 20:38:39 +02:00
|
|
|
HexGrid = new HexGrid();
|
2022-12-28 16:22:53 +01:00
|
|
|
_tileTypeRandom = new Random();
|
2023-05-21 17:24:37 +02:00
|
|
|
|
|
|
|
_worldOffscreenViewport = (Viewport)GetNode("WorldOffscreenViewport");
|
|
|
|
Debug.Assert(_worldOffscreenViewport != null);
|
|
|
|
_worldOffscreenViewport.Size = new Vector2(Size, Size);
|
|
|
|
_worldOffscreenTextureRect = (TextureRect)GetNode("WorldOffscreenViewport/TextureRect");
|
|
|
|
Debug.Assert(_worldOffscreenTextureRect != null);
|
|
|
|
_worldOffscreenTextureRect.SetSize(new Vector2(Size, Size));
|
|
|
|
|
|
|
|
_heightmapOffscreenViewport = (Viewport)GetNode("HeightmapOffscreenViewport");
|
|
|
|
Debug.Assert(_heightmapOffscreenViewport != null);
|
|
|
|
_heightmapOffscreenViewport.Size = new Vector2(Size, Size);
|
|
|
|
_heightmapOffscreenTextureRect = (TextureRect)GetNode("HeightmapOffscreenViewport/TextureRect");
|
|
|
|
Debug.Assert(_heightmapOffscreenTextureRect != null);
|
|
|
|
_heightmapOffscreenTextureRect.SetSize(new Vector2(Size, Size));
|
|
|
|
|
2023-06-11 22:04:22 +02:00
|
|
|
GetNode<Spatial>("Assets").Visible = false;
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
foreach (Spatial asset in GetNode<Node>("Assets/Rocks").GetChildren()) {
|
2023-06-11 22:04:22 +02:00
|
|
|
_rockAssets.Add(asset);
|
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
foreach (Spatial asset in GetNode<Node>("Assets/Grass").GetChildren()) {
|
2023-06-11 22:04:22 +02:00
|
|
|
_grassAssets.Add(asset);
|
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
foreach (Spatial asset in GetNode<Node>("Assets/Trees").GetChildren()) {
|
2023-06-22 18:34:39 +02:00
|
|
|
_treeAssets.Add(asset);
|
|
|
|
}
|
|
|
|
|
2023-08-12 12:55:17 +02:00
|
|
|
_chestScene = GD.Load<PackedScene>("res://entities/Chest.tscn");
|
|
|
|
|
2023-06-11 22:04:22 +02:00
|
|
|
_environmentNode = GetNode<Spatial>("Environment");
|
2023-06-23 15:39:07 +02:00
|
|
|
Entities = GetNode<Spatial>("Entities");
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-07-28 22:23:41 +02:00
|
|
|
ResetWorldImages(Size);
|
2022-12-28 16:22:53 +01:00
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public void ResetWorldImages(int size) {
|
2023-07-28 22:23:41 +02:00
|
|
|
GD.Print("Resetting World Images to size " + size);
|
|
|
|
|
|
|
|
Vector2 sizeVector = new Vector2(size, size);
|
2023-08-12 12:55:17 +02:00
|
|
|
|
2023-07-28 22:23:41 +02:00
|
|
|
ColormapImage = new Image();
|
|
|
|
ColormapImage.Create(size, size, false, Image.Format.Rgba8);
|
|
|
|
ColormapImage.FillRect(new Rect2(0, 0, size, size), Colors.Black);
|
|
|
|
_worldOffscreenTextureRect.SetSize(sizeVector);
|
|
|
|
_worldOffscreenViewport.Size = sizeVector;
|
|
|
|
|
|
|
|
HeightmapImage = new Image();
|
|
|
|
HeightmapImage.Create(size, size, false, Image.Format.Rf);
|
|
|
|
HeightmapImage.FillRect(new Rect2(0, 0, size, size), Colors.ForestGreen);
|
|
|
|
_heightmapOffscreenTextureRect.SetSize(sizeVector);
|
|
|
|
_heightmapOffscreenViewport.Size = sizeVector;
|
|
|
|
|
2023-08-12 18:16:45 +02:00
|
|
|
NavigationmapImage = new Image();
|
|
|
|
NavigationmapImage.Create(size, size, false, Image.Format.Rgb8);
|
|
|
|
NavigationmapImage.FillRect(new Rect2(0, 0, size, size), new Color(1, 1, 1));
|
2023-07-28 22:23:41 +02:00
|
|
|
}
|
2022-12-28 16:22:53 +01:00
|
|
|
|
2023-08-12 18:16:45 +02:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public void Generate(int size) {
|
2023-06-10 17:09:24 +02:00
|
|
|
GD.Print("Triggering generation for size: " + size);
|
2023-08-12 12:55:17 +02:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
if (Size != size) {
|
2023-07-28 22:23:41 +02:00
|
|
|
ResetWorldImages(size);
|
|
|
|
_resizeTriggered = true;
|
|
|
|
_resizeExtraFrameCount = 1;
|
|
|
|
}
|
2023-08-12 12:55:17 +02:00
|
|
|
|
2023-06-10 17:09:24 +02:00
|
|
|
Size = size;
|
2023-07-16 20:38:39 +02:00
|
|
|
|
2023-06-10 17:09:24 +02:00
|
|
|
_worldOffscreenViewport.Size = new Vector2(size, size);
|
|
|
|
_heightmapOffscreenViewport.Size = new Vector2(size, size);
|
2023-06-11 22:04:22 +02:00
|
|
|
|
2023-07-28 22:23:41 +02:00
|
|
|
_halfSize = Mathf.RoundToInt(size) / 2;
|
2023-07-16 20:38:39 +02:00
|
|
|
|
|
|
|
HexGrid.Obstacles.Clear();
|
|
|
|
HexGrid.Barriers.Clear();
|
|
|
|
|
2023-06-11 22:04:22 +02:00
|
|
|
OnMapGenerationStart();
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
switch (GenerationMapType) {
|
2023-07-16 20:38:39 +02:00
|
|
|
case MapType.Debug:
|
|
|
|
GenerateDebugMap();
|
2023-07-09 00:16:37 +02:00
|
|
|
break;
|
2023-07-16 20:38:39 +02:00
|
|
|
case MapType.Flat:
|
|
|
|
GenerateFlatMap();
|
2023-07-09 00:16:37 +02:00
|
|
|
break;
|
2023-07-16 20:38:39 +02:00
|
|
|
case MapType.Noise:
|
|
|
|
GenerateNoiseMap();
|
2023-07-09 00:16:37 +02:00
|
|
|
break;
|
|
|
|
}
|
2022-12-28 16:22:53 +01:00
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
private void GenerateDebugMap() {
|
2023-07-28 22:23:41 +02:00
|
|
|
ColormapImage = new Image();
|
|
|
|
ColormapImage.Create(Size, Size, false, Image.Format.Rgba8);
|
2023-05-20 12:27:30 +02:00
|
|
|
|
2023-07-28 22:23:41 +02:00
|
|
|
HeightmapImage = new Image();
|
|
|
|
HeightmapImage.Create(Size, Size, false, Image.Format.Rf);
|
2023-05-21 17:24:37 +02:00
|
|
|
|
2023-07-28 22:23:41 +02:00
|
|
|
HeightmapImage.Lock();
|
|
|
|
ColormapImage.Lock();
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
foreach (int coordX in Enumerable.Range(0, Size)) {
|
|
|
|
foreach (int coordY in Enumerable.Range(0, Size)) {
|
2023-07-28 22:23:41 +02:00
|
|
|
ColormapImage.SetPixel(coordX, coordY,
|
|
|
|
new Color((float)Mathf.Min(coordX, coordY) / Size, 0, 0));
|
|
|
|
HeightmapImage.SetPixel(coordX, coordY,
|
|
|
|
new Color((float)Mathf.Min(coordX, coordY) / Size, 0, 0));
|
2023-05-20 12:27:30 +02:00
|
|
|
}
|
|
|
|
}
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-07-09 00:16:37 +02:00
|
|
|
// Colormap.SetPixel(Size - 1, Size - 1, new Color(1, 1, 1, 1));
|
2023-07-28 22:23:41 +02:00
|
|
|
ColormapImage.Fill(Colors.ForestGreen);
|
|
|
|
ColormapImage.Unlock();
|
2023-07-09 00:16:37 +02:00
|
|
|
|
|
|
|
OnMapGenerationComplete();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
private void GenerateFlatMap() {
|
2023-07-28 22:23:41 +02:00
|
|
|
ColormapImage = new Image();
|
|
|
|
ColormapImage.Create(Size, Size, false, Image.Format.Rgba8);
|
2023-07-09 00:16:37 +02:00
|
|
|
|
2023-07-28 22:23:41 +02:00
|
|
|
HeightmapImage = new Image();
|
|
|
|
HeightmapImage.Create(Size, Size, false, Image.Format.Rf);
|
2023-07-09 00:16:37 +02:00
|
|
|
|
2023-07-28 22:23:41 +02:00
|
|
|
HeightmapImage.Lock();
|
|
|
|
ColormapImage.Lock();
|
2023-07-09 00:16:37 +02:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
foreach (int coordX in Enumerable.Range(0, Size)) {
|
|
|
|
foreach (int coordY in Enumerable.Range(0, Size)) {
|
2023-07-28 22:23:41 +02:00
|
|
|
HeightmapImage.SetPixel(coordX, coordY,
|
2023-10-05 18:17:48 +02:00
|
|
|
new Color(0.5f, 0.5f, 0.5f));
|
2023-07-09 00:16:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-28 22:23:41 +02:00
|
|
|
ColormapImage.Fill(Colors.ForestGreen);
|
|
|
|
ColormapImage.Unlock();
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-06-11 12:47:36 +02:00
|
|
|
OnMapGenerationComplete();
|
2022-12-28 16:22:53 +01:00
|
|
|
}
|
2023-05-21 17:24:37 +02:00
|
|
|
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
private void GenerateNoiseMap() {
|
2023-07-28 22:23:41 +02:00
|
|
|
HeightmapImage = new Image();
|
|
|
|
HeightmapImage.Create(Size, Size, false, Image.Format.Rgba8);
|
2023-05-20 12:27:30 +02:00
|
|
|
|
|
|
|
OpenSimplexNoise noiseGenerator = new OpenSimplexNoise();
|
2023-05-05 16:26:33 +02:00
|
|
|
|
2023-05-20 12:27:30 +02:00
|
|
|
noiseGenerator.Seed = Seed;
|
|
|
|
noiseGenerator.Octaves = 4;
|
|
|
|
noiseGenerator.Period = 20;
|
|
|
|
noiseGenerator.Persistence = 0.2f;
|
|
|
|
noiseGenerator.Lacunarity = 4;
|
2023-05-11 22:26:06 +02:00
|
|
|
|
2023-05-21 17:24:37 +02:00
|
|
|
ImageTexture heightmapTexture = new ImageTexture();
|
2023-07-28 22:23:41 +02:00
|
|
|
heightmapTexture.CreateFromImage(noiseGenerator.GetSeamlessImage(Size));
|
2023-05-21 17:24:37 +02:00
|
|
|
heightmapTexture.Flags = 0;
|
|
|
|
_heightmapOffscreenTextureRect.Texture = heightmapTexture;
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-06-11 12:47:36 +02:00
|
|
|
OnHeightMapChanged();
|
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
private void OnMapGenerationStart() {
|
|
|
|
foreach (Node child in _environmentNode.GetChildren()) {
|
2023-06-11 22:04:22 +02:00
|
|
|
child.QueueFree();
|
|
|
|
}
|
2023-07-09 00:16:37 +02:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
foreach (Node child in Entities.GetChildren()) {
|
2023-06-23 15:39:07 +02:00
|
|
|
child.QueueFree();
|
|
|
|
}
|
2023-06-11 22:04:22 +02:00
|
|
|
}
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
private void OnHeightMapChanged() {
|
2023-07-28 22:23:41 +02:00
|
|
|
GD.Print("Triggering rendering of height map");
|
2023-06-10 17:09:24 +02:00
|
|
|
_currentGenerationState = GenerationState.Heightmap;
|
2023-06-13 22:29:05 +02:00
|
|
|
_heightmapOffscreenViewport.RenderTargetUpdateMode = Viewport.UpdateMode.Once;
|
2023-05-05 16:26:33 +02:00
|
|
|
}
|
2022-12-28 16:22:53 +01:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
private void OnMapGenerationComplete() {
|
2023-06-11 12:47:36 +02:00
|
|
|
_currentGenerationState = GenerationState.Done;
|
2023-07-28 22:23:41 +02:00
|
|
|
_worldOffscreenViewport.RenderTargetUpdateMode = Viewport.UpdateMode.Disabled;
|
|
|
|
_heightmapOffscreenViewport.RenderTargetUpdateMode = Viewport.UpdateMode.Disabled;
|
|
|
|
_resizeTriggered = false;
|
2023-08-12 12:55:17 +02:00
|
|
|
|
2023-07-28 22:23:41 +02:00
|
|
|
HeightmapImage.Lock();
|
2023-06-11 12:47:36 +02:00
|
|
|
EmitSignal("WorldGenerated");
|
|
|
|
}
|
2023-05-20 12:27:30 +02:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
private Spatial SelectAsset(Vector2 offsetCoord, Array<Spatial> assets, Random randomGenerator,
|
|
|
|
double probability) {
|
|
|
|
if (randomGenerator.NextDouble() < 1.0 - probability) {
|
2023-06-11 22:04:22 +02:00
|
|
|
return null;
|
|
|
|
}
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-06-11 22:04:22 +02:00
|
|
|
int assetIndex = randomGenerator.Next(assets.Count);
|
2023-06-22 18:34:39 +02:00
|
|
|
Spatial assetInstance = (Spatial)assets[assetIndex].Duplicate();
|
2023-06-11 22:04:22 +02:00
|
|
|
Transform assetTransform = Transform.Identity;
|
2023-07-16 22:00:17 +02:00
|
|
|
assetTransform.origin = GetHexCenterFromOffset(offsetCoord);
|
2023-09-19 20:32:22 +02:00
|
|
|
assetTransform.origin.y = GetHeightAtOffset(offsetCoord);
|
2023-06-22 18:34:39 +02:00
|
|
|
assetTransform.basis =
|
|
|
|
assetTransform.basis.Rotated(Vector3.Up, (float)(randomGenerator.NextDouble() * Mathf.Pi * 2));
|
2023-06-11 22:04:22 +02:00
|
|
|
assetInstance.Transform = assetTransform;
|
|
|
|
|
|
|
|
return assetInstance;
|
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
private bool IsColorEqualApprox(Color colorA, Color colorB) {
|
2023-06-11 22:04:22 +02:00
|
|
|
Vector3 colorDifference = new Vector3(colorA.r - colorB.r, colorA.g - colorB.g, colorA.b - colorB.b);
|
|
|
|
return colorDifference.LengthSquared() < 0.1 * 0.1;
|
|
|
|
}
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
private bool IsColorWater(Color color) {
|
2023-07-16 20:38:39 +02:00
|
|
|
return (color.r == 0 && color.g == 0 && color.b > 0.01);
|
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public void MarkCellUnwalkable(HexCell cell) {
|
2023-08-12 18:16:45 +02:00
|
|
|
HexGrid.AddObstacle(cell);
|
|
|
|
NavigationmapImage.Lock();
|
|
|
|
NavigationmapImage.SetPixelv(OffsetToTextureCoord(cell.OffsetCoords), Colors.Red);
|
|
|
|
NavigationmapImage.Unlock();
|
|
|
|
}
|
2023-11-10 11:11:08 +01:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
private void PopulateEnvironment() {
|
2023-06-11 22:04:22 +02:00
|
|
|
Random environmentRandom = new Random(Seed);
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-07-28 22:23:41 +02:00
|
|
|
ColormapImage.Lock();
|
|
|
|
HeightmapImage.Lock();
|
2023-08-12 12:55:17 +02:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
foreach (int textureCoordU in Enumerable.Range(0, Size)) {
|
|
|
|
foreach (int textureCoordV in Enumerable.Range(0, Size)) {
|
2023-07-28 22:23:41 +02:00
|
|
|
Color colorValue = ColormapImage.GetPixel(textureCoordU, textureCoordV);
|
2023-07-16 22:00:17 +02:00
|
|
|
Vector2 textureCoord = new Vector2(textureCoordU, textureCoordV);
|
|
|
|
HexCell cell = TextureCoordToCell(textureCoord);
|
|
|
|
Vector2 offsetCoord = cell.OffsetCoords;
|
2023-06-11 22:04:22 +02:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
if (IsColorEqualApprox(colorValue, RockColor)) {
|
2023-06-11 22:04:22 +02:00
|
|
|
Spatial rockAsset = SelectAsset(offsetCoord, _rockAssets, environmentRandom, 0.15);
|
2023-11-18 22:32:57 +01:00
|
|
|
if (rockAsset != null) {
|
2023-06-11 22:04:22 +02:00
|
|
|
_environmentNode.AddChild(rockAsset);
|
2023-08-12 18:16:45 +02:00
|
|
|
MarkCellUnwalkable(cell);
|
2023-06-11 22:04:22 +02:00
|
|
|
}
|
2023-11-18 22:32:57 +01:00
|
|
|
} else if (IsColorEqualApprox(colorValue, GrassColor)) {
|
2023-06-11 22:04:22 +02:00
|
|
|
Spatial grassAsset = SelectAsset(offsetCoord, _grassAssets, environmentRandom, 0.35);
|
2023-11-18 22:32:57 +01:00
|
|
|
if (grassAsset != null) {
|
2023-06-11 22:04:22 +02:00
|
|
|
_environmentNode.AddChild(grassAsset);
|
2023-06-22 18:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Spatial treeAsset = SelectAsset(offsetCoord, _treeAssets, environmentRandom, 0.10);
|
2023-11-18 22:32:57 +01:00
|
|
|
if (treeAsset != null) {
|
2023-06-23 15:39:07 +02:00
|
|
|
Entities.AddChild(treeAsset);
|
2023-08-12 18:16:45 +02:00
|
|
|
MarkCellUnwalkable(cell);
|
2023-11-18 22:32:57 +01:00
|
|
|
} else if (environmentRandom.NextDouble() < 0.01) {
|
2023-08-12 12:55:17 +02:00
|
|
|
Chest chestAsset = (Chest)_chestScene.Instance();
|
|
|
|
Transform assetTransform = Transform.Identity;
|
|
|
|
assetTransform.origin = GetHexCenterFromOffset(offsetCoord);
|
2023-09-19 20:32:22 +02:00
|
|
|
assetTransform.origin.y = GetHeightAtOffset(offsetCoord);
|
2023-08-12 12:55:17 +02:00
|
|
|
chestAsset.Transform = assetTransform;
|
|
|
|
Entities.AddChild(chestAsset);
|
2023-08-12 18:16:45 +02:00
|
|
|
MarkCellUnwalkable(cell);
|
2023-08-12 12:55:17 +02:00
|
|
|
}
|
2023-11-18 22:32:57 +01:00
|
|
|
} else if (IsColorWater(colorValue)) {
|
2023-08-12 18:16:45 +02:00
|
|
|
MarkCellUnwalkable(cell);
|
2023-06-11 22:04:22 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-07-28 22:23:41 +02:00
|
|
|
HeightmapImage.Unlock();
|
|
|
|
ColormapImage.Unlock();
|
2023-06-11 22:04:22 +02:00
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public override void _Process(float delta) {
|
|
|
|
if (_resizeTriggered && _resizeExtraFrameCount > 0) {
|
2023-07-28 22:23:41 +02:00
|
|
|
_resizeExtraFrameCount--;
|
|
|
|
return;
|
2023-08-12 12:55:17 +02:00
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
if (_currentGenerationState == GenerationState.Heightmap) {
|
2023-07-28 22:23:41 +02:00
|
|
|
HeightmapImage.CopyFrom(_heightmapOffscreenViewport.GetTexture().GetData());
|
2023-08-12 12:55:17 +02:00
|
|
|
|
2023-06-10 17:09:24 +02:00
|
|
|
_currentGenerationState = GenerationState.Color;
|
2023-05-21 17:24:37 +02:00
|
|
|
ImageTexture imageTexture = new ImageTexture();
|
2023-07-28 22:23:41 +02:00
|
|
|
imageTexture.CreateFromImage(HeightmapImage);
|
2023-05-21 17:24:37 +02:00
|
|
|
imageTexture.Flags = 0;
|
|
|
|
_worldOffscreenTextureRect.Texture = imageTexture;
|
2023-07-28 22:23:41 +02:00
|
|
|
|
|
|
|
GD.Print("Triggering rendering of color map");
|
|
|
|
|
2023-06-13 22:29:05 +02:00
|
|
|
_worldOffscreenViewport.RenderTargetUpdateMode = Viewport.UpdateMode.Once;
|
2023-07-28 22:23:41 +02:00
|
|
|
_resizeExtraFrameCount = 1;
|
2023-11-18 22:32:57 +01:00
|
|
|
} else if (_currentGenerationState == GenerationState.Color) {
|
2023-07-28 22:23:41 +02:00
|
|
|
ColormapImage = new Image();
|
|
|
|
ColormapImage.Create(Size, Size, false, Image.Format.Rgb8);
|
|
|
|
ColormapImage.CopyFrom(_worldOffscreenViewport.GetTexture().GetData());
|
2023-05-21 17:24:37 +02:00
|
|
|
|
2023-06-11 22:04:22 +02:00
|
|
|
_currentGenerationState = GenerationState.Objects;
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-06-11 22:04:22 +02:00
|
|
|
PopulateEnvironment();
|
2023-11-18 22:32:57 +01:00
|
|
|
} else if (_currentGenerationState == GenerationState.Objects) {
|
2023-06-11 12:47:36 +02:00
|
|
|
OnMapGenerationComplete();
|
2023-05-21 17:24:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public bool IsOffsetCoordValid(Vector2 offsetCoord) {
|
2023-07-28 22:23:41 +02:00
|
|
|
return ((int)Math.Clamp(offsetCoord.x, -(float)Size / 2, (float)Size / 2 - 1) == (int)offsetCoord.x
|
|
|
|
&& (int)Math.Clamp(offsetCoord.y, -(float)Size / 2, (float)Size / 2 - 1) == (int)offsetCoord.y);
|
2022-12-28 16:22:53 +01:00
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public Vector2 OffsetToTextureCoord(Vector2 offsetCoord) {
|
2023-06-10 17:09:24 +02:00
|
|
|
Vector2 mapSize = Vector2.One * Size;
|
|
|
|
Vector2 textureCoord = (offsetCoord + mapSize / 2).PosMod(mapSize);
|
2023-05-20 12:27:30 +02:00
|
|
|
return textureCoord;
|
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public void SetHeightAtOffset(Vector2 offsetCoord, float height) {
|
2023-05-20 12:27:30 +02:00
|
|
|
Vector2 textureCoord = OffsetToTextureCoord(offsetCoord);
|
2023-05-21 17:24:37 +02:00
|
|
|
|
2023-07-28 22:23:41 +02:00
|
|
|
HeightmapImage.SetPixel((int)textureCoord.x, (int)textureCoord.y, new Color(height, 0f, 0f));
|
2023-05-20 12:27:30 +02:00
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public float GetHeightAtOffset(Vector2 offsetCoord) {
|
|
|
|
if (_currentGenerationState != GenerationState.Done) {
|
2023-05-21 17:24:37 +02:00
|
|
|
return 0f;
|
|
|
|
}
|
2023-06-22 18:34:39 +02:00
|
|
|
|
2023-05-21 17:24:37 +02:00
|
|
|
Vector2 textureCoord = OffsetToTextureCoord(offsetCoord);
|
|
|
|
|
2023-11-10 11:11:08 +01:00
|
|
|
float heightmapHeight = (HeightmapImage.GetPixel((int)textureCoord.x, (int)(textureCoord.y)).r - 0.5f) *
|
|
|
|
HeightScale;
|
2023-08-12 12:55:17 +02:00
|
|
|
|
2023-09-19 20:32:22 +02:00
|
|
|
if (heightmapHeight <= 0)
|
|
|
|
heightmapHeight -= 0.03f;
|
|
|
|
else
|
|
|
|
heightmapHeight = 0f;
|
2023-06-10 17:09:24 +02:00
|
|
|
|
2023-09-19 20:32:22 +02:00
|
|
|
return heightmapHeight;
|
2022-12-28 16:22:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public void SetTileColorAtOffset(Vector2 offsetCoord, Color color) {
|
2023-07-09 00:16:37 +02:00
|
|
|
Vector2 textureCoord = OffsetToTextureCoord(offsetCoord);
|
2023-07-16 20:38:39 +02:00
|
|
|
|
2023-07-28 22:23:41 +02:00
|
|
|
ColormapImage.Lock();
|
|
|
|
ColormapImage.SetPixel((int)textureCoord.x, (int)textureCoord.y, color);
|
|
|
|
ColormapImage.Unlock();
|
2023-07-09 00:16:37 +02:00
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public Vector2 WorldToOffsetCoords(Vector3 worldCoord) {
|
2023-07-16 22:00:17 +02:00
|
|
|
return HexGrid.GetHexAt(new Vector2(worldCoord.x, worldCoord.z)).OffsetCoords +
|
|
|
|
Vector2.One * Mathf.Round(Size / 2f);
|
2022-12-28 16:22:53 +01:00
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public Vector3 GetTileWorldCenterFromOffset(Vector2 offsetCoord) {
|
2023-07-16 20:38:39 +02:00
|
|
|
Vector2 tileCenter = HexGrid.GetHexCenterFromOffset(offsetCoord - Vector2.One * Mathf.Round(Size / 2f));
|
2023-07-09 00:16:37 +02:00
|
|
|
return new Vector3(tileCenter.x, GetHeightAtOffset(offsetCoord), tileCenter.y);
|
2023-01-03 17:46:55 +01:00
|
|
|
}
|
2023-06-29 23:07:29 +02:00
|
|
|
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public Vector3 GetHexCenterFromOffset(Vector2 offsetCoord) {
|
2023-07-16 20:38:39 +02:00
|
|
|
Vector2 tileCenter = HexGrid.GetHexCenterFromOffset(offsetCoord);
|
2023-06-29 23:07:29 +02:00
|
|
|
return new Vector3(tileCenter.x, GetHeightAtOffset(offsetCoord), tileCenter.y);
|
|
|
|
}
|
2023-07-16 22:00:17 +02:00
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public HexCell TextureCoordToCell(Vector2 textureCoord) {
|
2023-07-16 22:00:17 +02:00
|
|
|
return HexCell.FromOffsetCoords(textureCoord - Vector2.One * _halfSize);
|
|
|
|
}
|
|
|
|
|
2023-11-18 22:32:57 +01:00
|
|
|
public Vector2 TextureCoordToOffsetCoord(Vector2 textureCoord) {
|
2023-07-16 22:00:17 +02:00
|
|
|
return TextureCoordToCell(textureCoord).OffsetCoords;
|
|
|
|
}
|
2022-12-28 16:22:53 +01:00
|
|
|
}
|