Files
TheDeclineOfWarriors/Assets/Scripts/WorldGen/RuntimeWorldProfileFactory.cs
T
2026-03-29 02:26:31 +07:00

238 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace InfiniteWorld
{
public static class RuntimeWorldProfileFactory
{
public static WorldAutotileProfile CreateFallbackProfile()
{
WorldAutotileProfile profile = ScriptableObject.CreateInstance<WorldAutotileProfile>();
profile.name = "RuntimeFallbackWorldProfile";
Color grass = new Color(0.35f, 0.62f, 0.26f, 1f);
Color wallFill = new Color(0.48f, 0.37f, 0.22f, 1f);
Color wallBorder = new Color(0.29f, 0.21f, 0.12f, 1f);
profile.baseGroundTile = ProceduralWorldArt.CreateSolidTile("base_grass", grass, 0.06f);
profile.wallTiles.center = ProceduralWorldArt.CreateFeatureTile("wall_center", wallFill, wallBorder, false, false, false, false, InnerCornerMask.None, true);
profile.wallTiles.top = ProceduralWorldArt.CreateFeatureTile("wall_top", wallFill, wallBorder, true, false, false, false, InnerCornerMask.None, true);
profile.wallTiles.right = ProceduralWorldArt.CreateFeatureTile("wall_right", wallFill, wallBorder, false, true, false, false, InnerCornerMask.None, true);
profile.wallTiles.bottom = ProceduralWorldArt.CreateFeatureTile("wall_bottom", wallFill, wallBorder, false, false, true, false, InnerCornerMask.None, true);
profile.wallTiles.left = ProceduralWorldArt.CreateFeatureTile("wall_left", wallFill, wallBorder, false, false, false, true, InnerCornerMask.None, true);
profile.wallTiles.outerTopLeft = ProceduralWorldArt.CreateFeatureTile("wall_outer_tl", wallFill, wallBorder, true, false, false, true, InnerCornerMask.None, true);
profile.wallTiles.outerTopRight = ProceduralWorldArt.CreateFeatureTile("wall_outer_tr", wallFill, wallBorder, true, true, false, false, InnerCornerMask.None, true);
profile.wallTiles.outerBottomRight = ProceduralWorldArt.CreateFeatureTile("wall_outer_br", wallFill, wallBorder, false, true, true, false, InnerCornerMask.None, true);
profile.wallTiles.outerBottomLeft = ProceduralWorldArt.CreateFeatureTile("wall_outer_bl", wallFill, wallBorder, false, false, true, true, InnerCornerMask.None, true);
profile.wallTiles.innerTopLeft = ProceduralWorldArt.CreateFeatureTile("wall_inner_tl", wallFill, wallBorder, false, false, false, false, InnerCornerMask.TopLeft, true);
profile.wallTiles.innerTopRight = ProceduralWorldArt.CreateFeatureTile("wall_inner_tr", wallFill, wallBorder, false, false, false, false, InnerCornerMask.TopRight, true);
profile.wallTiles.innerBottomRight = ProceduralWorldArt.CreateFeatureTile("wall_inner_br", wallFill, wallBorder, false, false, false, false, InnerCornerMask.BottomRight, true);
profile.wallTiles.innerBottomLeft = ProceduralWorldArt.CreateFeatureTile("wall_inner_bl", wallFill, wallBorder, false, false, false, false, InnerCornerMask.BottomLeft, true);
profile.environmentTiles.Add(new EnvironmentTileEntry
{
id = "Bush",
tile = ProceduralWorldArt.CreateDecorationTile("env_bush", new Color(0.15f, 0.45f, 0.18f, 1f), new Color(0.23f, 0.58f, 0.25f, 1f), DecorationPattern.Bush),
weight = 1.4f
});
profile.environmentTiles.Add(new EnvironmentTileEntry
{
id = "FlowerBlue",
tile = ProceduralWorldArt.CreateDecorationTile("env_flower_blue", new Color(0.44f, 0.62f, 0.96f, 1f), new Color(0.98f, 0.91f, 0.52f, 1f), DecorationPattern.Flower),
weight = 0.75f
});
profile.environmentTiles.Add(new EnvironmentTileEntry
{
id = "Rock",
tile = ProceduralWorldArt.CreateDecorationTile("env_rock", new Color(0.48f, 0.48f, 0.52f, 1f), new Color(0.69f, 0.69f, 0.74f, 1f), DecorationPattern.Rocks),
weight = 0.9f
});
return profile;
}
public static List<ChunkTemplate> CreateFallbackTemplates(int size)
{
List<ChunkTemplate> templates = new List<ChunkTemplate>
{
CreateCross(size),
CreateStraightHorizontal(size),
CreateStraightVertical(size),
CreateCorner(size, true, true, false, false),
CreateCorner(size, false, true, true, false),
CreateCorner(size, false, false, true, true),
CreateCorner(size, true, false, false, true),
CreateTJunction(size, true, true, true, false),
CreateTJunction(size, false, true, true, true),
CreateTJunction(size, true, false, true, true),
CreateTJunction(size, true, true, false, true)
};
return templates;
}
private static ChunkTemplate CreateCross(int size)
{
ChunkTemplate template = CreateTemplate("Runtime_Cross", size, size, true, true, true, true);
DrawRoom(template, 3, 3, size - 6, size - 6);
DrawPillar(template, 4, 4);
DrawPillar(template, size - 5, 4);
DrawPillar(template, 4, size - 5);
DrawPillar(template, size - 5, size - 5);
ScatterEnvironment(template, 3);
return template;
}
private static ChunkTemplate CreateStraightHorizontal(int size)
{
ChunkTemplate template = CreateTemplate("Runtime_Straight_H", size, size, false, true, false, true);
DrawRoom(template, 2, 4, size - 4, size - 8);
DrawSideAlcoves(template, horizontal: true);
ScatterEnvironment(template, 2);
return template;
}
private static ChunkTemplate CreateStraightVertical(int size)
{
ChunkTemplate template = CreateTemplate("Runtime_Straight_V", size, size, true, false, true, false);
DrawRoom(template, 4, 2, size - 8, size - 4);
DrawSideAlcoves(template, horizontal: false);
ScatterEnvironment(template, 2);
return template;
}
private static ChunkTemplate CreateCorner(int size, bool top, bool right, bool bottom, bool left)
{
ChunkTemplate template = CreateTemplate($"Runtime_Corner_{top}_{right}_{bottom}_{left}", size, size, top, right, bottom, left);
DrawRoom(template, 3, 3, size - 6, size - 6);
if (!top)
{
DrawWallLine(template, 5, size - 5, size - 6, size - 5);
}
if (!right)
{
DrawWallLine(template, size - 5, 5, size - 5, size - 6);
}
if (!bottom)
{
DrawWallLine(template, 5, 4, size - 6, 4);
}
if (!left)
{
DrawWallLine(template, 4, 5, 4, size - 6);
}
ScatterEnvironment(template, 2);
return template;
}
private static ChunkTemplate CreateTJunction(int size, bool top, bool right, bool bottom, bool left)
{
ChunkTemplate template = CreateTemplate($"Runtime_T_{top}_{right}_{bottom}_{left}", size, size, top, right, bottom, left);
DrawRoom(template, 2, 2, size - 4, size - 4);
DrawPillar(template, size / 2, size / 2);
ScatterEnvironment(template, 3);
return template;
}
private static ChunkTemplate CreateTemplate(string name, int width, int height, bool top, bool right, bool bottom, bool left)
{
ChunkTemplate template = ScriptableObject.CreateInstance<ChunkTemplate>();
template.name = name;
template.Resize(width, height);
template.exitTop = top;
template.exitRight = right;
template.exitBottom = bottom;
template.exitLeft = left;
template.ApplyBorderWallsFromExits(3);
return template;
}
private static void DrawRoom(ChunkTemplate template, int xMin, int yMin, int width, int height)
{
for (int x = xMin; x < xMin + width; x++)
{
template.SetWall(x, yMin, true);
template.SetWall(x, yMin + height - 1, true);
}
for (int y = yMin; y < yMin + height; y++)
{
template.SetWall(xMin, y, true);
template.SetWall(xMin + width - 1, y, true);
}
template.CarveExit(ChunkExit.Top, 3);
template.CarveExit(ChunkExit.Right, 3);
template.CarveExit(ChunkExit.Bottom, 3);
template.CarveExit(ChunkExit.Left, 3);
}
private static void DrawPillar(ChunkTemplate template, int x, int y)
{
for (int py = -1; py <= 1; py++)
{
for (int px = -1; px <= 1; px++)
{
template.SetWall(x + px, y + py, true);
}
}
}
private static void DrawSideAlcoves(ChunkTemplate template, bool horizontal)
{
if (horizontal)
{
DrawWallLine(template, template.width / 2 - 1, 5, template.width / 2 - 1, 7);
DrawWallLine(template, template.width / 2 + 1, template.height - 8, template.width / 2 + 1, template.height - 6);
}
else
{
DrawWallLine(template, 5, template.height / 2 - 1, 7, template.height / 2 - 1);
DrawWallLine(template, template.width - 8, template.height / 2 + 1, template.width - 6, template.height / 2 + 1);
}
}
private static void DrawWallLine(ChunkTemplate template, int x0, int y0, int x1, int y1)
{
int dx = Math.Sign(x1 - x0);
int dy = Math.Sign(y1 - y0);
int x = x0;
int y = y0;
while (true)
{
template.SetWall(x, y, true);
if (x == x1 && y == y1)
{
break;
}
if (x != x1)
{
x += dx;
}
if (y != y1)
{
y += dy;
}
}
}
private static void ScatterEnvironment(ChunkTemplate template, int spacing)
{
for (int y = 2; y < template.height - 2; y += spacing + 2)
{
for (int x = 2; x < template.width - 2; x += spacing + 3)
{
if (!template.GetWall(x, y))
{
template.SetEnvironment(x, y, ((x + y) & 1) == 0);
}
}
}
}
}
}