using System; using System.Collections.Generic; using UnityEngine; namespace InfiniteWorld { public static class RuntimeWorldProfileFactory { public static WorldAutotileProfile CreateFallbackProfile() { WorldAutotileProfile profile = ScriptableObject.CreateInstance(); 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 CreateFallbackTemplates(int size) { List templates = new List { 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(); 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); } } } } } }