Cleaned up project with better structure.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
[gd_scene format=3 uid="uid://4by1t1x6m4yt"]
|
[gd_scene format=3 uid="uid://4by1t1x6m4yt"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://qdjn5oqn6p5d" path="res://Scripts/Crafting/ItemDisplay.cs" id="1_if7q5"]
|
[ext_resource type="Script" uid="uid://qdjn5oqn6p5d" path="res://Scripts/UI/Inventory/ItemDisplay.cs" id="1_if7q5"]
|
||||||
|
|
||||||
[node name="Item" type="PanelContainer" unique_id=247502695 node_paths=PackedStringArray("texture", "text", "amount")]
|
[node name="Item" type="PanelContainer" unique_id=247502695 node_paths=PackedStringArray("texture", "text", "amount")]
|
||||||
anchors_preset = 14
|
anchors_preset = 14
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[gd_scene format=3 uid="uid://cinn18bl736rk"]
|
[gd_scene format=3 uid="uid://cinn18bl736rk"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://b6kxwmuhmruul" path="res://Scripts/DSL/NodeDisplay.cs" id="1_qemp1"]
|
[ext_resource type="Script" uid="uid://b6kxwmuhmruul" path="res://Scripts/UI/DSL/NodeDisplay.cs" id="1_qemp1"]
|
||||||
[ext_resource type="Texture2D" uid="uid://wq8yc0u0ee33" path="res://Assets/Images/TrashSymbol.png" id="2_loic7"]
|
[ext_resource type="Texture2D" uid="uid://wq8yc0u0ee33" path="res://Assets/Images/TrashSymbol.png" id="2_loic7"]
|
||||||
|
|
||||||
[node name="Craft" type="PanelContainer" unique_id=247502695 node_paths=PackedStringArray("editorDisplay", "listDisplay")]
|
[node name="Craft" type="PanelContainer" unique_id=247502695 node_paths=PackedStringArray("editorDisplay", "listDisplay")]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[gd_scene format=3 uid="uid://dit4u45jegwv0"]
|
[gd_scene format=3 uid="uid://dit4u45jegwv0"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://b6kxwmuhmruul" path="res://Scripts/DSL/NodeDisplay.cs" id="1_3kgh4"]
|
[ext_resource type="Script" uid="uid://b6kxwmuhmruul" path="res://Scripts/UI/DSL/NodeDisplay.cs" id="1_3kgh4"]
|
||||||
[ext_resource type="Texture2D" uid="uid://wq8yc0u0ee33" path="res://Assets/Images/TrashSymbol.png" id="2_6eg2n"]
|
[ext_resource type="Texture2D" uid="uid://wq8yc0u0ee33" path="res://Assets/Images/TrashSymbol.png" id="2_6eg2n"]
|
||||||
|
|
||||||
[node name="Explore" type="PanelContainer" unique_id=1474470717 node_paths=PackedStringArray("editorDisplay", "listDisplay")]
|
[node name="Explore" type="PanelContainer" unique_id=1474470717 node_paths=PackedStringArray("editorDisplay", "listDisplay")]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[gd_scene format=3 uid="uid://com0ou37wj2xo"]
|
[gd_scene format=3 uid="uid://com0ou37wj2xo"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://b6kxwmuhmruul" path="res://Scripts/DSL/NodeDisplay.cs" id="1_ve3v1"]
|
[ext_resource type="Script" uid="uid://b6kxwmuhmruul" path="res://Scripts/UI/DSL/NodeDisplay.cs" id="1_ve3v1"]
|
||||||
[ext_resource type="Texture2D" uid="uid://wq8yc0u0ee33" path="res://Assets/Images/TrashSymbol.png" id="2_u1say"]
|
[ext_resource type="Texture2D" uid="uid://wq8yc0u0ee33" path="res://Assets/Images/TrashSymbol.png" id="2_u1say"]
|
||||||
|
|
||||||
[node name="Harvest" type="PanelContainer" unique_id=1323721153 node_paths=PackedStringArray("editorDisplay", "listDisplay")]
|
[node name="Harvest" type="PanelContainer" unique_id=1323721153 node_paths=PackedStringArray("editorDisplay", "listDisplay")]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[gd_scene format=3 uid="uid://by0khq5dmxjvm"]
|
[gd_scene format=3 uid="uid://by0khq5dmxjvm"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://b6kxwmuhmruul" path="res://Scripts/DSL/NodeDisplay.cs" id="1_mexpj"]
|
[ext_resource type="Script" uid="uid://b6kxwmuhmruul" path="res://Scripts/UI/DSL/NodeDisplay.cs" id="1_mexpj"]
|
||||||
[ext_resource type="Texture2D" uid="uid://wq8yc0u0ee33" path="res://Assets/Images/TrashSymbol.png" id="2_5ujwv"]
|
[ext_resource type="Texture2D" uid="uid://wq8yc0u0ee33" path="res://Assets/Images/TrashSymbol.png" id="2_5ujwv"]
|
||||||
|
|
||||||
[node name="Move" type="PanelContainer" unique_id=1474470717 node_paths=PackedStringArray("editorDisplay", "listDisplay")]
|
[node name="Move" type="PanelContainer" unique_id=1474470717 node_paths=PackedStringArray("editorDisplay", "listDisplay")]
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[gd_scene format=3 uid="uid://ck10wk10me3tx"]
|
[gd_scene format=3 uid="uid://ck10wk10me3tx"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://Scripts/WorldGeneration/Layer.cs" id="1_trar1"]
|
[ext_resource type="Script" path="res://Scripts/World/Layer.cs" id="1_trar1"]
|
||||||
|
|
||||||
[node name="Node3D" type="Node3D" unique_id=724642284]
|
[node name="Node3D" type="Node3D" unique_id=724642284]
|
||||||
script = ExtResource("1_trar1")
|
script = ExtResource("1_trar1")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[gd_scene format=3 uid="uid://dciwxejdji2lg"]
|
[gd_scene format=3 uid="uid://dciwxejdji2lg"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://cjae60v4c60vb" path="res://Prefabs/Robot/RobotVisual.tscn" id="2_3hvm5"]
|
[ext_resource type="PackedScene" uid="uid://cjae60v4c60vb" path="res://Prefabs/Robot/RobotVisual.tscn" id="2_3hvm5"]
|
||||||
[ext_resource type="Script" uid="uid://e0pgy7jya41y" path="res://Scripts/Robot/Robot.cs" id="2_j80uv"]
|
[ext_resource type="Script" uid="uid://e0pgy7jya41y" path="res://Scripts/Gameplay/Robots/Robot.cs" id="2_j80uv"]
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_vquur"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_vquur"]
|
||||||
size = Vector3(1.1176758, 0.7307129, 1.0234375)
|
size = Vector3(1.1176758, 0.7307129, 1.0234375)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[gd_scene format=3 uid="uid://dribqey54i62n"]
|
[gd_scene format=3 uid="uid://dribqey54i62n"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://dcxom1paffp0p" path="res://Scripts/Robot/RobotDisplay.cs" id="1_ltmdd"]
|
[ext_resource type="Script" uid="uid://dcxom1paffp0p" path="res://Scripts/UI/Robots/RobotDisplay.cs" id="1_ltmdd"]
|
||||||
|
|
||||||
[node name="Robot" type="PanelContainer" unique_id=247502695 node_paths=PackedStringArray("listItem", "currentScript")]
|
[node name="Robot" type="PanelContainer" unique_id=247502695 node_paths=PackedStringArray("listItem", "currentScript")]
|
||||||
anchors_preset = 14
|
anchors_preset = 14
|
||||||
|
|||||||
+9
-9
@@ -1,21 +1,21 @@
|
|||||||
[gd_scene format=3 uid="uid://cgsmfi2s51cbd"]
|
[gd_scene format=3 uid="uid://cgsmfi2s51cbd"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://br2udyi6t8yvf" path="res://Scripts/WorldGeneration/World.cs" id="1_7lihs"]
|
[ext_resource type="Script" uid="uid://br2udyi6t8yvf" path="res://Scripts/World/World.cs" id="1_7lihs"]
|
||||||
[ext_resource type="Script" uid="uid://dqrdb3bvws6b6" path="res://Scripts/Helpers/SteamworksHandler.cs" id="2_b2bpf"]
|
[ext_resource type="Script" uid="uid://dqrdb3bvws6b6" path="res://Scripts/Core/SteamworksHandler.cs" id="2_b2bpf"]
|
||||||
[ext_resource type="Script" uid="uid://c7khr6oist3ku" path="res://Scripts/Camera3d.cs" id="3_7lihs"]
|
[ext_resource type="Script" uid="uid://c7khr6oist3ku" path="res://Scripts/UI/Common/Camera3d.cs" id="3_7lihs"]
|
||||||
[ext_resource type="Script" uid="uid://bm7knir4552j5" path="res://Scripts/Helpers/UIHandler.cs" id="4_fgofq"]
|
[ext_resource type="Script" uid="uid://bm7knir4552j5" path="res://Scripts/UI/Common/UIHandler.cs" id="4_fgofq"]
|
||||||
[ext_resource type="Script" uid="uid://bsd6n6b06a4pe" path="res://Scripts/DSL/CodingWindow.cs" id="6_7lihs"]
|
[ext_resource type="Script" uid="uid://bsd6n6b06a4pe" path="res://Scripts/UI/DSL/CodingWindow.cs" id="6_7lihs"]
|
||||||
[ext_resource type="Script" uid="uid://k6vlo7ulvtep" path="res://Scripts/Robot/RobotList.cs" id="7_2irst"]
|
[ext_resource type="Script" uid="uid://k6vlo7ulvtep" path="res://Scripts/UI/Robots/RobotList.cs" id="7_2irst"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cpq7ppe8bw2bq" path="res://Scenes/Options.tscn" id="8_71axn"]
|
[ext_resource type="PackedScene" uid="uid://cpq7ppe8bw2bq" path="res://Scenes/Options.tscn" id="8_71axn"]
|
||||||
[ext_resource type="Script" uid="uid://fegfbcnlk8p5" path="res://Scripts/WorldGeneration/Map.cs" id="8_bf53h"]
|
[ext_resource type="Script" uid="uid://fegfbcnlk8p5" path="res://Scripts/World/Map.cs" id="8_bf53h"]
|
||||||
[ext_resource type="Texture2D" uid="uid://deuxffyhsrinn" path="res://Assets/Images/EnergySymbol.png" id="9_71axn"]
|
[ext_resource type="Texture2D" uid="uid://deuxffyhsrinn" path="res://Assets/Images/EnergySymbol.png" id="9_71axn"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dje86ro2e37xl" path="res://Assets/Images/Resources/WaterSymbol.png" id="10_71axn"]
|
[ext_resource type="Texture2D" uid="uid://dje86ro2e37xl" path="res://Assets/Images/Resources/WaterSymbol.png" id="10_71axn"]
|
||||||
[ext_resource type="Texture2D" uid="uid://d068gyi3e48cv" path="res://Assets/Images/MapSymbol.png" id="11_3cx6b"]
|
[ext_resource type="Texture2D" uid="uid://d068gyi3e48cv" path="res://Assets/Images/MapSymbol.png" id="11_3cx6b"]
|
||||||
[ext_resource type="Script" uid="uid://com0u7nqag6pp" path="res://Scripts/Crafting/InventoryDisplay.cs" id="11_acvyw"]
|
[ext_resource type="Script" uid="uid://com0u7nqag6pp" path="res://Scripts/UI/Inventory/InventoryDisplay.cs" id="11_acvyw"]
|
||||||
[ext_resource type="Texture2D" uid="uid://ban872p4eh4gi" path="res://Assets/Images/RobotSymbol.png" id="11_dahhg"]
|
[ext_resource type="Texture2D" uid="uid://ban872p4eh4gi" path="res://Assets/Images/RobotSymbol.png" id="11_dahhg"]
|
||||||
[ext_resource type="Texture2D" uid="uid://ciehcg34et0q3" path="res://Assets/Images/InventorySymbol.png" id="11_wxwew"]
|
[ext_resource type="Texture2D" uid="uid://ciehcg34et0q3" path="res://Assets/Images/InventorySymbol.png" id="11_wxwew"]
|
||||||
[ext_resource type="Texture2D" uid="uid://b77mo4fhklnja" path="res://Assets/Images/OptionsSymbol.png" id="12_3so38"]
|
[ext_resource type="Texture2D" uid="uid://b77mo4fhklnja" path="res://Assets/Images/OptionsSymbol.png" id="12_3so38"]
|
||||||
[ext_resource type="Script" uid="uid://drscsrkfphpy7" path="res://Scripts/Research/ResearchList.cs" id="12_4q8tf"]
|
[ext_resource type="Script" uid="uid://drscsrkfphpy7" path="res://Scripts/UI/Research/ResearchList.cs" id="12_4q8tf"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dt84awx33mulb" path="res://Assets/Images/ResearchSymbol.png" id="13_alh3a"]
|
[ext_resource type="Texture2D" uid="uid://dt84awx33mulb" path="res://Assets/Images/ResearchSymbol.png" id="13_alh3a"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bmcpkt6mae2qi" path="res://Assets/Images/AlarmSign.png" id="13_x3xnh"]
|
[ext_resource type="Texture2D" uid="uid://bmcpkt6mae2qi" path="res://Assets/Images/AlarmSign.png" id="13_x3xnh"]
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[gd_scene format=3 uid="uid://dlommaelbbw2b"]
|
[gd_scene format=3 uid="uid://dlommaelbbw2b"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://dda0bhhqspbr0" path="res://Scripts/Menus/MainMenu.cs" id="1_tt5f1"]
|
[ext_resource type="Script" uid="uid://dda0bhhqspbr0" path="res://Scripts/UI/Menus/MainMenu.cs" id="1_tt5f1"]
|
||||||
[ext_resource type="Texture2D" uid="uid://ban872p4eh4gi" path="res://Assets/Images/RobotSymbol.png" id="2_853f1"]
|
[ext_resource type="Texture2D" uid="uid://ban872p4eh4gi" path="res://Assets/Images/RobotSymbol.png" id="2_853f1"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dt84awx33mulb" path="res://Assets/Images/ResearchSymbol.png" id="3_df05h"]
|
[ext_resource type="Texture2D" uid="uid://dt84awx33mulb" path="res://Assets/Images/ResearchSymbol.png" id="3_df05h"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dm0w2gtcsa5l4" path="res://Assets/Images/Items/Batteryv1Symbol.png" id="4_8um5k"]
|
[ext_resource type="Texture2D" uid="uid://dm0w2gtcsa5l4" path="res://Assets/Images/Items/Batteryv1Symbol.png" id="4_8um5k"]
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
public class FileHandler()
|
public class FileHandler
|
||||||
{
|
{
|
||||||
|
private const string ScriptDirectory = "user://scripts";
|
||||||
|
private const string ScriptExtension = ".dsl";
|
||||||
|
|
||||||
public static void CreateScriptDirectory()
|
public static void CreateScriptDirectory()
|
||||||
{
|
{
|
||||||
DirAccess.MakeDirRecursiveAbsolute("user://scripts");
|
DirAccess.MakeDirRecursiveAbsolute(ScriptDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SaveProgram(string filename, string content)
|
public static void SaveProgram(string filename, string content)
|
||||||
{
|
{
|
||||||
CreateScriptDirectory();
|
CreateScriptDirectory();
|
||||||
string path = $"user://scripts/{filename}.dsl";
|
string path = GetProgramPath(filename);
|
||||||
|
|
||||||
FileAccess file = FileAccess.Open(path, FileAccess.ModeFlags.Write);
|
FileAccess file = FileAccess.Open(path, FileAccess.ModeFlags.Write);
|
||||||
file.StoreString(content);
|
file.StoreString(content);
|
||||||
@@ -22,9 +25,11 @@ public class FileHandler()
|
|||||||
CreateScriptDirectory();
|
CreateScriptDirectory();
|
||||||
List<string> programs = new List<string>();
|
List<string> programs = new List<string>();
|
||||||
|
|
||||||
DirAccess dir = DirAccess.Open("user://scripts");
|
DirAccess dir = DirAccess.Open(ScriptDirectory);
|
||||||
if (dir == null)
|
if (dir == null)
|
||||||
|
{
|
||||||
return programs;
|
return programs;
|
||||||
|
}
|
||||||
|
|
||||||
dir.ListDirBegin();
|
dir.ListDirBegin();
|
||||||
while (true)
|
while (true)
|
||||||
@@ -33,9 +38,9 @@ public class FileHandler()
|
|||||||
if (fileName == "")
|
if (fileName == "")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!dir.CurrentIsDir() && fileName.EndsWith(".dsl"))
|
if (!dir.CurrentIsDir() && fileName.EndsWith(ScriptExtension))
|
||||||
{
|
{
|
||||||
programs.Add(fileName.Replace(".dsl", ""));
|
programs.Add(fileName.Replace(ScriptExtension, ""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dir.ListDirEnd();
|
dir.ListDirEnd();
|
||||||
@@ -46,12 +51,19 @@ public class FileHandler()
|
|||||||
public static string LoadProgram(string name)
|
public static string LoadProgram(string name)
|
||||||
{
|
{
|
||||||
CreateScriptDirectory();
|
CreateScriptDirectory();
|
||||||
string path = $"user://scripts/{name}.dsl";
|
string path = GetProgramPath(name);
|
||||||
|
|
||||||
if (!FileAccess.FileExists(path))
|
if (!FileAccess.FileExists(path))
|
||||||
|
{
|
||||||
return "";
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
FileAccess file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
|
FileAccess file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
|
||||||
return file.GetAsText();
|
return file.GetAsText();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private static string GetProgramPath(string filename)
|
||||||
|
{
|
||||||
|
return $"{ScriptDirectory}/{filename}{ScriptExtension}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,15 +4,14 @@ using Godot;
|
|||||||
|
|
||||||
public partial class GameData
|
public partial class GameData
|
||||||
{
|
{
|
||||||
public static bool DEBUGMODE = false;
|
public static bool debugMode = false;
|
||||||
public static Random rand = new Random(seed);
|
public static Random rand = new Random(seed);
|
||||||
public static Layer[] map;
|
public static Layer[] map;
|
||||||
//Current layer the player wants to see
|
|
||||||
public static int currentLayer = 0;
|
public static int currentLayer = 0;
|
||||||
//The layer that is currently visible
|
|
||||||
public static int visibleLayer = 0;
|
public static int visibleLayer = 0;
|
||||||
public static int lowestLayer = 0;
|
public static int lowestLayer = 0;
|
||||||
//Determines if the player can move the camera or not (Necessary for input and options menu)
|
|
||||||
public static bool canMove = true;
|
public static bool canMove = true;
|
||||||
public static int maxRobotCount = 1000;
|
public static int maxRobotCount = 1000;
|
||||||
public static List<Robot> robots = new List<Robot>();
|
public static List<Robot> robots = new List<Robot>();
|
||||||
@@ -22,19 +21,12 @@ public partial class GameData
|
|||||||
public static SortedDictionary<string, ItemData> availableItems = ResourceLoader.LoadItems();
|
public static SortedDictionary<string, ItemData> availableItems = ResourceLoader.LoadItems();
|
||||||
public static Dictionary<string, Research> availableResearch = ResourceLoader.LoadResearch();
|
public static Dictionary<string, Research> availableResearch = ResourceLoader.LoadResearch();
|
||||||
|
|
||||||
//--- PLAYER ADJUSTABLE VALUES ---
|
|
||||||
//Color used in primary objects (e.g. Robots)
|
|
||||||
public static Color primaryColor = new Color("#276ac2");
|
public static Color primaryColor = new Color("#276ac2");
|
||||||
//Color used in lights
|
|
||||||
public static Color lightColor = new Color("#7efff5");
|
public static Color lightColor = new Color("#7efff5");
|
||||||
//Amount of layers generated
|
|
||||||
public static int ruinSize = 10;
|
public static int ruinSize = 10;
|
||||||
//Width+Height of layers
|
|
||||||
public static int layerSize = 20;
|
public static int layerSize = 20;
|
||||||
//Seed used for all random generation except WFC
|
|
||||||
public static int seed = 12345;
|
public static int seed = 12345;
|
||||||
|
|
||||||
//--- PLAYER VALUES ---
|
|
||||||
public static Inventory inventory = new Inventory();
|
public static Inventory inventory = new Inventory();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
public partial class ResourceLoader
|
||||||
|
{
|
||||||
|
private const string LayerPrefabPath = "res://Prefabs/Layer.tscn";
|
||||||
|
private const string RobotPrefabPath = "res://Prefabs/Robot/Robot.tscn";
|
||||||
|
private const string RobotDisplayPath = "res://Prefabs/Robot/RobotDisplay.tscn";
|
||||||
|
private const string ItemDisplayPath = "res://Prefabs/Crafting/ItemDisplay.tscn";
|
||||||
|
private const string RecipesPath = "res://Assets/Recipes.json";
|
||||||
|
private const string ResearchPath = "res://Assets/Research.json";
|
||||||
|
|
||||||
|
public static PackedScene LoadLayerPrefab()
|
||||||
|
{
|
||||||
|
return GD.Load<PackedScene>(LayerPrefabPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PackedScene LoadRobotPrefab()
|
||||||
|
{
|
||||||
|
return GD.Load<PackedScene>(RobotPrefabPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PackedScene LoadRobotDisplay()
|
||||||
|
{
|
||||||
|
return GD.Load<PackedScene>(RobotDisplayPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PackedScene LoadItemDisplay()
|
||||||
|
{
|
||||||
|
return GD.Load<PackedScene>(ItemDisplayPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Texture2D LoadPath(string path)
|
||||||
|
{
|
||||||
|
return GD.Load<Texture2D>(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dictionary<string, MeshInstance3D> LoadTiles()
|
||||||
|
{
|
||||||
|
Dictionary<string, MeshInstance3D> tileMeshes = new Dictionary<string, MeshInstance3D>();
|
||||||
|
PackedScene tileCollection = GD.Load<PackedScene>($"res://Assets/Objects/Tiles.glb");
|
||||||
|
Node root = tileCollection.Instantiate();
|
||||||
|
foreach (MeshInstance3D child in root.GetChildren())
|
||||||
|
{
|
||||||
|
tileMeshes.Add(child.Name.ToString().ToLower(), child);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tileMeshes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dictionary<string, MeshInstance3D> LoadDecorations()
|
||||||
|
{
|
||||||
|
Dictionary<string, MeshInstance3D> decorationMeshes = new Dictionary<string, MeshInstance3D>();
|
||||||
|
PackedScene decorationCollection = GD.Load<PackedScene>($"res://Assets/Objects/Decorations.glb");
|
||||||
|
Node root = decorationCollection.Instantiate();
|
||||||
|
foreach (MeshInstance3D child in root.GetChildren())
|
||||||
|
{
|
||||||
|
decorationMeshes.Add(child.Name.ToString().ToLower(), child);
|
||||||
|
}
|
||||||
|
|
||||||
|
return decorationMeshes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dictionary<ProgramNode, PackedScene> LoadDSLNodes()
|
||||||
|
{
|
||||||
|
Dictionary<ProgramNode, PackedScene> nodes = new Dictionary<ProgramNode, PackedScene>()
|
||||||
|
{
|
||||||
|
{ new MoveNode(), GD.Load<PackedScene>("res://Prefabs/DSL/MoveNode.tscn") },
|
||||||
|
{ new HarvestNode(), GD.Load<PackedScene>("res://Prefabs/DSL/HarvestNode.tscn") },
|
||||||
|
{ new CraftNode(), GD.Load<PackedScene>("res://Prefabs/DSL/CraftNode.tscn") },
|
||||||
|
{ new ExploreNode(), GD.Load<PackedScene>("res://Prefabs/DSL/ExploreNode.tscn") }
|
||||||
|
};
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dictionary<string, Texture2D> LoadResourceSymbols()
|
||||||
|
{
|
||||||
|
Dictionary<string, Texture2D> symbols = new Dictionary<string, Texture2D>()
|
||||||
|
{
|
||||||
|
{ "iron_ore", GD.Load<Texture2D>("res://Assets/Images/Resources/IronSymbol.png") },
|
||||||
|
{ "tin_ore", GD.Load<Texture2D>("res://Assets/Images/Resources/TinSymbol.png") },
|
||||||
|
{ "copper_ore", GD.Load<Texture2D>("res://Assets/Images/Resources/CopperSymbol.png") },
|
||||||
|
{ "mushroom", GD.Load<Texture2D>("res://Assets/Images/Resources/MushroomSymbol.png") },
|
||||||
|
{ "spider_silk", GD.Load<Texture2D>("res://Assets/Images/Resources/SpiderSilkSymbol.png") },
|
||||||
|
{ "coal", GD.Load<Texture2D>("res://Assets/Images/Resources/CoalSymbol.png") },
|
||||||
|
{ "water", GD.Load<Texture2D>("res://Assets/Images/Resources/WaterSymbol.png") },
|
||||||
|
{ "stone", GD.Load<Texture2D>("res://Assets/Images/Resources/StoneSymbol.png") },
|
||||||
|
};
|
||||||
|
return symbols;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SortedDictionary<string, ItemData> LoadItems()
|
||||||
|
{
|
||||||
|
|
||||||
|
FileAccess file = FileAccess.Open(RecipesPath, FileAccess.ModeFlags.Read);
|
||||||
|
string json = file.GetAsText();
|
||||||
|
|
||||||
|
SortedDictionary<string, ItemData> result = new SortedDictionary<string, ItemData>();
|
||||||
|
|
||||||
|
List<ItemData> items = JsonSerializer.Deserialize<List<ItemData>>(json);
|
||||||
|
if (items == null) return result;
|
||||||
|
|
||||||
|
foreach (ItemData item in items)
|
||||||
|
{
|
||||||
|
result.Add(item.Id, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dictionary<string, Research> LoadResearch()
|
||||||
|
{
|
||||||
|
|
||||||
|
FileAccess file = FileAccess.Open(ResearchPath, FileAccess.ModeFlags.Read);
|
||||||
|
string json = file.GetAsText();
|
||||||
|
|
||||||
|
Dictionary<string, Research> result = new Dictionary<string, Research>();
|
||||||
|
|
||||||
|
List<ResearchData> researches = JsonSerializer.Deserialize<List<ResearchData>>(json);
|
||||||
|
if (researches == null) return result;
|
||||||
|
|
||||||
|
foreach (ResearchData research in researches)
|
||||||
|
{
|
||||||
|
result.Add(research.Id, new Research(research));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
using GodotSteam;
|
using GodotSteam;
|
||||||
|
|
||||||
public partial class SteamworksHandler : Node
|
public partial class SteamworksHandler : Node
|
||||||
{
|
{
|
||||||
|
[Export] private bool enableSteam = false;
|
||||||
|
private bool isSteamInitialized = false;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
return;
|
if (!enableSteam) return;
|
||||||
|
|
||||||
SteamInitExStatus status = Steam.SteamInitEx(false).Status;
|
SteamInitExStatus status = Steam.SteamInitEx(false).Status;
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
{
|
{
|
||||||
@@ -14,15 +19,20 @@ public partial class SteamworksHandler : Node
|
|||||||
|
|
||||||
GD.Print("Steam initialized!");
|
GD.Print("Steam initialized!");
|
||||||
GD.Print("User: " + Steam.GetPersonaName());
|
GD.Print("User: " + Steam.GetPersonaName());
|
||||||
|
isSteamInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
|
if (!isSteamInitialized) return;
|
||||||
|
|
||||||
Steam.RunCallbacks();
|
Steam.RunCallbacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _ExitTree()
|
public override void _ExitTree()
|
||||||
{
|
{
|
||||||
|
if (!isSteamInitialized) return;
|
||||||
|
|
||||||
Steam.SteamShutdown();
|
Steam.SteamShutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using Godot;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
public partial class ItemDisplay : PanelContainer
|
|
||||||
{
|
|
||||||
[Export] public TextureRect texture;
|
|
||||||
[Export] public RichTextLabel text;
|
|
||||||
[Export] public RichTextLabel amount;
|
|
||||||
public Item item;
|
|
||||||
// Called when the node enters the scene tree for the first time.
|
|
||||||
public override void _Ready()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
||||||
public override void _Process(double delta)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using System.Linq;
|
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
public class CraftNode : ProgramNode
|
public class CraftNode : ProgramNode
|
||||||
@@ -16,11 +15,13 @@ public class CraftNode : ProgramNode
|
|||||||
lastExecutionMessage = "No Item selected";
|
lastExecutionMessage = "No Item selected";
|
||||||
return NodeResult.FAILURE;
|
return NodeResult.FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (amount <= 0)
|
if (amount <= 0)
|
||||||
{
|
{
|
||||||
lastExecutionMessage = "Amount has to be atleast 1";
|
lastExecutionMessage = "Amount has to be atleast 1";
|
||||||
return NodeResult.FAILURE;
|
return NodeResult.FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GameData.inventory.CanCraft(selectedItem.data.Inputs, amount))
|
if (!GameData.inventory.CanCraft(selectedItem.data.Inputs, amount))
|
||||||
{
|
{
|
||||||
lastExecutionMessage = "Not enough items to craft this";
|
lastExecutionMessage = "Not enough items to craft this";
|
||||||
@@ -67,12 +68,13 @@ public class CraftNode : ProgramNode
|
|||||||
options.AddItem("Select item...");
|
options.AddItem("Select item...");
|
||||||
foreach (ItemData item in GameData.availableItems.Values)
|
foreach (ItemData item in GameData.availableItems.Values)
|
||||||
{
|
{
|
||||||
if(GameData.availableResearch[item.Research].state != ResearchState.RESEARCHED) continue;
|
if (GameData.availableResearch[item.Research].state != ResearchState.RESEARCHED) continue;
|
||||||
if (item.Inputs.Count > 0)
|
if (item.Inputs.Count > 0)
|
||||||
{
|
{
|
||||||
options.AddItem(item.GetCraftingDisplay());
|
options.AddItem(item.GetCraftingDisplay());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedItem != null)
|
if (selectedItem != null)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < options.ItemCount; i++)
|
for (int i = 0; i < options.ItemCount; i++)
|
||||||
|
|||||||
@@ -16,9 +16,10 @@ public class ExploreNode : ProgramNode
|
|||||||
if (pathPoints == null)
|
if (pathPoints == null)
|
||||||
{
|
{
|
||||||
int safetyCounter = 0;
|
int safetyCounter = 0;
|
||||||
|
int layerRange = Math.Max(GameData.lowestLayer, 1);
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
targetPosition = new Vector3I(GameData.rand.Next(GameData.layerSize), GameData.rand.Next(GameData.lowestLayer), GameData.rand.Next(GameData.layerSize));
|
targetPosition = new Vector3I(GameData.rand.Next(GameData.layerSize), GameData.rand.Next(layerRange), GameData.rand.Next(GameData.layerSize));
|
||||||
if (!GameData.map[targetPosition.Y].tiles[targetPosition.X, targetPosition.Z].wasVisited) break;
|
if (!GameData.map[targetPosition.Y].tiles[targetPosition.X, targetPosition.Z].wasVisited) break;
|
||||||
safetyCounter++;
|
safetyCounter++;
|
||||||
if (safetyCounter > Math.Pow(GameData.layerSize, 2) * 2)
|
if (safetyCounter > Math.Pow(GameData.layerSize, 2) * 2)
|
||||||
@@ -29,7 +30,7 @@ public class ExploreNode : ProgramNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pathPoints ??= [.. Pathfinding.GetPath(Pathfinding.GetClosestStartPoint(robot.Position), targetPosition)];
|
pathPoints ??= new List<Vector3>(Pathfinding.GetPath(Pathfinding.GetClosestStartPoint(robot.Position), targetPosition));
|
||||||
|
|
||||||
if (pathPoints.Count <= 0)
|
if (pathPoints.Count <= 0)
|
||||||
{
|
{
|
||||||
@@ -50,6 +51,7 @@ public class ExploreNode : ProgramNode
|
|||||||
{
|
{
|
||||||
tile.VisitTile();
|
tile.VisitTile();
|
||||||
}
|
}
|
||||||
|
|
||||||
pathPoints.Remove(pathPoints[0]);
|
pathPoints.Remove(pathPoints[0]);
|
||||||
if (pathPoints.Count <= 0)
|
if (pathPoints.Count <= 0)
|
||||||
{
|
{
|
||||||
@@ -84,16 +86,14 @@ public class ExploreNode : ProgramNode
|
|||||||
|
|
||||||
public override void ReadParameters(NodeDisplay display)
|
public override void ReadParameters(NodeDisplay display)
|
||||||
{
|
{
|
||||||
//Currently does nothing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Setup(NodeDisplay display)
|
public override void Setup(NodeDisplay display)
|
||||||
{
|
{
|
||||||
//Currently does nothing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Save()
|
public override string Save()
|
||||||
{
|
{
|
||||||
return $"Name: {DisplayText}";
|
return $"Name: {DisplayText}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ public class HarvestNode : ProgramNode
|
|||||||
|
|
||||||
public override void ReadParameters(NodeDisplay display)
|
public override void ReadParameters(NodeDisplay display)
|
||||||
{
|
{
|
||||||
//Currently does nothing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ProgramNode Duplicate()
|
public override ProgramNode Duplicate()
|
||||||
@@ -47,11 +46,10 @@ public class HarvestNode : ProgramNode
|
|||||||
|
|
||||||
public override void Setup(NodeDisplay display)
|
public override void Setup(NodeDisplay display)
|
||||||
{
|
{
|
||||||
//Currently does nothing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Save()
|
public override string Save()
|
||||||
{
|
{
|
||||||
return $"Name: {DisplayText}";
|
return $"Name: {DisplayText}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
@@ -13,12 +12,14 @@ public class MoveNode : ProgramNode
|
|||||||
}
|
}
|
||||||
public override NodeResult Execute(Robot robot, double delta)
|
public override NodeResult Execute(Robot robot, double delta)
|
||||||
{
|
{
|
||||||
pathPoints ??= [.. Pathfinding.GetPath(Pathfinding.GetClosestStartPoint(robot.Position), targetPosition)];
|
pathPoints ??= new List<Vector3>(Pathfinding.GetPath(Pathfinding.GetClosestStartPoint(robot.Position), targetPosition));
|
||||||
|
|
||||||
if (pathPoints.Count <= 0)
|
if (pathPoints.Count <= 0)
|
||||||
{
|
{
|
||||||
lastExecutionMessage = "No path available";
|
lastExecutionMessage = "No path available";
|
||||||
return NodeResult.FAILURE;
|
return NodeResult.FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
startPosition = robot.Position;
|
startPosition = robot.Position;
|
||||||
Vector3 target = pathPoints[0] - startPosition;
|
Vector3 target = pathPoints[0] - startPosition;
|
||||||
float distance = target.Length();
|
float distance = target.Length();
|
||||||
@@ -32,6 +33,7 @@ public class MoveNode : ProgramNode
|
|||||||
{
|
{
|
||||||
tile.VisitTile();
|
tile.VisitTile();
|
||||||
}
|
}
|
||||||
|
|
||||||
pathPoints.Remove(pathPoints[0]);
|
pathPoints.Remove(pathPoints[0]);
|
||||||
if (pathPoints.Count <= 0)
|
if (pathPoints.Count <= 0)
|
||||||
{
|
{
|
||||||
@@ -74,11 +76,10 @@ public class MoveNode : ProgramNode
|
|||||||
|
|
||||||
public override void Setup(NodeDisplay display)
|
public override void Setup(NodeDisplay display)
|
||||||
{
|
{
|
||||||
//Currently does nothing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Save()
|
public override string Save()
|
||||||
{
|
{
|
||||||
return $"Name: {DisplayText}, Position: ({targetPosition.X}|{targetPosition.Y}|{targetPosition.Z})";
|
return $"Name: {DisplayText}, Position: ({targetPosition.X}|{targetPosition.Y}|{targetPosition.Z})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using Godot;
|
|
||||||
|
|
||||||
public class Building
|
public class Building
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,14 @@
|
|||||||
using Godot;
|
|
||||||
|
|
||||||
public class GameResource
|
public class GameResource
|
||||||
{
|
{
|
||||||
public string name;
|
public string name;
|
||||||
int currentAmount;
|
|
||||||
int maxAmount;
|
|
||||||
bool isEndless;
|
|
||||||
float extractionSpeed;
|
|
||||||
double timeSinceLastExtraction;
|
|
||||||
public ItemData item;
|
public ItemData item;
|
||||||
|
|
||||||
|
private int currentAmount;
|
||||||
|
private int maxAmount;
|
||||||
|
private bool isEndless;
|
||||||
|
private float extractionSpeed;
|
||||||
|
private double timeSinceLastExtraction;
|
||||||
|
|
||||||
public GameResource(string name)
|
public GameResource(string name)
|
||||||
{
|
{
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@@ -24,14 +23,16 @@ public class GameResource
|
|||||||
{
|
{
|
||||||
timeSinceLastExtraction += delta;
|
timeSinceLastExtraction += delta;
|
||||||
if (timeSinceLastExtraction < extractionSpeed) return false;
|
if (timeSinceLastExtraction < extractionSpeed) return false;
|
||||||
|
|
||||||
timeSinceLastExtraction = 0;
|
timeSinceLastExtraction = 0;
|
||||||
if(isEndless) return true;
|
if (isEndless) return true;
|
||||||
|
|
||||||
if (currentAmount > 0)
|
if (currentAmount > 0)
|
||||||
{
|
{
|
||||||
currentAmount--;
|
currentAmount--;
|
||||||
|
return true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,4 +40,4 @@ public class GameResource
|
|||||||
{
|
{
|
||||||
return (isEndless || currentAmount > 0) && GameData.availableResearch[item.Research].state == ResearchState.RESEARCHED;
|
return (isEndless || currentAmount > 0) && GameData.availableResearch[item.Research].state == ResearchState.RESEARCHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Godot;
|
|
||||||
|
|
||||||
public class Ingredient
|
public class Ingredient
|
||||||
{
|
{
|
||||||
[JsonPropertyName("item")]
|
[JsonPropertyName("item")]
|
||||||
public string Item {get; set;}
|
public string Item { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("amount")]
|
[JsonPropertyName("amount")]
|
||||||
public int Amount {get;set;}
|
public int Amount { get; set; }
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Godot;
|
|
||||||
|
|
||||||
public class Inventory
|
public class Inventory
|
||||||
{
|
{
|
||||||
public List<Item> items = new();
|
public List<Item> items = new List<Item>();
|
||||||
|
|
||||||
public int maxInventorySize = 8;
|
public int maxInventorySize = 8;
|
||||||
public event EventHandler OnInventoryUpdate;
|
public event EventHandler OnInventoryUpdate;
|
||||||
@@ -15,36 +14,33 @@ public class Inventory
|
|||||||
if (inventoryItem != null)
|
if (inventoryItem != null)
|
||||||
{
|
{
|
||||||
inventoryItem.currentAmount += amount;
|
inventoryItem.currentAmount += amount;
|
||||||
OnInventoryUpdate?.Invoke(this, EventArgs.Empty);
|
NotifyInventoryChanged();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (items.Count < maxInventorySize)
|
||||||
{
|
{
|
||||||
if (items.Count < maxInventorySize)
|
items.Add(item);
|
||||||
{
|
items[items.Count - 1].currentAmount += amount;
|
||||||
items.Add(item);
|
NotifyInventoryChanged();
|
||||||
items[items.Count - 1].currentAmount += amount;
|
return true;
|
||||||
OnInventoryUpdate?.Invoke(this, EventArgs.Empty);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanCraft(List<Ingredient> neededIngredients, int amount)
|
public bool CanCraft(List<Ingredient> neededIngredients, int amount)
|
||||||
{
|
{
|
||||||
bool canCraft = true;
|
|
||||||
Item item;
|
|
||||||
foreach (Ingredient ingredient in neededIngredients)
|
foreach (Ingredient ingredient in neededIngredients)
|
||||||
{
|
{
|
||||||
item = items.Find(x => x.data.Id == ingredient.Item && x.currentAmount >= ingredient.Amount * amount);
|
Item item = items.Find(x => x.data.Id == ingredient.Item && x.currentAmount >= ingredient.Amount * amount);
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
canCraft = false;
|
return false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return canCraft;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveItem(string id, int amount)
|
public void RemoveItem(string id, int amount)
|
||||||
@@ -53,7 +49,12 @@ public class Inventory
|
|||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
item.currentAmount -= amount;
|
item.currentAmount -= amount;
|
||||||
OnInventoryUpdate?.Invoke(this, EventArgs.Empty);
|
NotifyInventoryChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private void NotifyInventoryChanged()
|
||||||
|
{
|
||||||
|
OnInventoryUpdate?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,3 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using Godot;
|
|
||||||
|
|
||||||
public class Item
|
public class Item
|
||||||
{
|
{
|
||||||
public ItemData data;
|
public ItemData data;
|
||||||
@@ -15,14 +11,16 @@ public class Item
|
|||||||
if (elapsedCraftTime >= data.CraftTime)
|
if (elapsedCraftTime >= data.CraftTime)
|
||||||
{
|
{
|
||||||
elapsedCraftTime -= data.CraftTime;
|
elapsedCraftTime -= data.CraftTime;
|
||||||
if(!GameData.inventory.AddItem(this, 1))
|
if (!GameData.inventory.AddItem(this, 1))
|
||||||
{
|
{
|
||||||
return CraftingResult.FAILED;
|
return CraftingResult.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Ingredient ingredient in data.Inputs)
|
foreach (Ingredient ingredient in data.Inputs)
|
||||||
{
|
{
|
||||||
GameData.inventory.RemoveItem(ingredient.Item, ingredient.Amount);
|
GameData.inventory.RemoveItem(ingredient.Item, ingredient.Amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
amountCrafted++;
|
amountCrafted++;
|
||||||
if (amountCrafted >= amount)
|
if (amountCrafted >= amount)
|
||||||
{
|
{
|
||||||
@@ -31,7 +29,7 @@ public class Item
|
|||||||
return CraftingResult.FINISHED;
|
return CraftingResult.FINISHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CraftingResult.CRAFTING;
|
return CraftingResult.CRAFTING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using Godot;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
@@ -47,13 +46,16 @@ public class ItemData
|
|||||||
|
|
||||||
public string GetCraftingDisplay()
|
public string GetCraftingDisplay()
|
||||||
{
|
{
|
||||||
string result = "";
|
string result = GetReadableName() + ": \r";
|
||||||
result += GetReadableName() + ": \r";
|
|
||||||
foreach (Ingredient ingredient in Inputs)
|
foreach (Ingredient ingredient in Inputs)
|
||||||
{
|
{
|
||||||
result += $"{GetReadableName(ingredient.Item)} ({ingredient.Amount}),\r";
|
result += $"{GetReadableName(ingredient.Item)} ({ingredient.Amount}),\r";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Inputs.Count <= 0) return result;
|
||||||
|
|
||||||
result = result.Remove(result.Length - 2);
|
result = result.Remove(result.Length - 2);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
using Godot;
|
|
||||||
|
|
||||||
public class Research
|
public class Research
|
||||||
{
|
{
|
||||||
public ResearchData data;
|
public ResearchData data;
|
||||||
@@ -23,12 +21,14 @@ public class Research
|
|||||||
}
|
}
|
||||||
paidResources = true;
|
paidResources = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
elapsedResearchTime += delta;
|
elapsedResearchTime += delta;
|
||||||
if (elapsedResearchTime >= data.CraftTime)
|
if (elapsedResearchTime >= data.CraftTime)
|
||||||
{
|
{
|
||||||
state = ResearchState.RESEARCHED;
|
state = ResearchState.RESEARCHED;
|
||||||
return ResearchResult.FINISHED;
|
return ResearchResult.FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResearchResult.RESEARCHING;
|
return ResearchResult.RESEARCHING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Godot;
|
|
||||||
|
|
||||||
public class ResearchData
|
public class ResearchData
|
||||||
{
|
{
|
||||||
@@ -29,4 +28,4 @@ public class ResearchData
|
|||||||
{
|
{
|
||||||
return readable.ToLower().Replace(" ", "_");
|
return readable.ToLower().Replace(" ", "_");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,16 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
public partial class Robot : Node3D
|
public partial class Robot : Node3D
|
||||||
{
|
{
|
||||||
List<ProgramNode> nodes;
|
private List<ProgramNode> nodes = new List<ProgramNode>();
|
||||||
bool isExecuting = false;
|
private bool isExecuting = false;
|
||||||
ProgramNode currentNode;
|
private ProgramNode currentNode;
|
||||||
|
|
||||||
public string currentProgram;
|
public string currentProgram;
|
||||||
public string currentMessage = "";
|
public string currentMessage = "";
|
||||||
|
|
||||||
public override void _Ready()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
if (isExecuting)
|
if (isExecuting)
|
||||||
@@ -38,7 +33,7 @@ public partial class Robot : Node3D
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(currentMessage.Length <= 0)
|
else if (currentMessage.Length <= 0)
|
||||||
{
|
{
|
||||||
currentMessage = "No script executing";
|
currentMessage = "No script executing";
|
||||||
}
|
}
|
||||||
@@ -49,7 +44,9 @@ public partial class Robot : Node3D
|
|||||||
|
|
||||||
public void SetupExecution(List<ProgramNode> nodes)
|
public void SetupExecution(List<ProgramNode> nodes)
|
||||||
{
|
{
|
||||||
this.nodes = [.. nodes];
|
if (nodes.Count <= 0) return;
|
||||||
|
|
||||||
|
this.nodes = new List<ProgramNode>(nodes);
|
||||||
isExecuting = true;
|
isExecuting = true;
|
||||||
currentNode = nodes[0];
|
currentNode = nodes[0];
|
||||||
}
|
}
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
using Godot;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
public class MultiMeshHandler
|
|
||||||
{
|
|
||||||
private Dictionary<string, MultiMeshInstance3D> multiMeshes;
|
|
||||||
|
|
||||||
public MultiMeshHandler(Dictionary<string, MultiMeshInstance3D> multiMeshes)
|
|
||||||
{
|
|
||||||
this.multiMeshes = multiMeshes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Build(List<TileRenderData> tiles)
|
|
||||||
{
|
|
||||||
foreach (var mm in multiMeshes.Values)
|
|
||||||
mm.Multimesh.InstanceCount = 0;
|
|
||||||
|
|
||||||
var batches = new Dictionary<string, List<Transform3D>>();
|
|
||||||
|
|
||||||
foreach (var tile in tiles)
|
|
||||||
{
|
|
||||||
if (!batches.ContainsKey(tile.MeshKey))
|
|
||||||
batches[tile.MeshKey] = new List<Transform3D>();
|
|
||||||
|
|
||||||
batches[tile.MeshKey].Add(tile.Transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var kvp in batches)
|
|
||||||
{
|
|
||||||
var mm = multiMeshes[kvp.Key].Multimesh;
|
|
||||||
var list = kvp.Value;
|
|
||||||
|
|
||||||
mm.InstanceCount = list.Count;
|
|
||||||
|
|
||||||
for (int i = 0; i < list.Count; i++)
|
|
||||||
mm.SetInstanceTransform(i, list[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
using Godot;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.Json;
|
|
||||||
public partial class ResourceLoader
|
|
||||||
{
|
|
||||||
|
|
||||||
public static PackedScene LoadLayerPrefab()
|
|
||||||
{
|
|
||||||
return GD.Load<PackedScene>($"res://Prefabs/Layer.tscn");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PackedScene LoadRobotPrefab()
|
|
||||||
{
|
|
||||||
return GD.Load<PackedScene>($"res://Prefabs/Robot/Robot.tscn");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PackedScene LoadRobotDisplay()
|
|
||||||
{
|
|
||||||
return GD.Load<PackedScene>($"res://Prefabs/Robot/RobotDisplay.tscn");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PackedScene LoadItemDisplay()
|
|
||||||
{
|
|
||||||
return GD.Load<PackedScene>($"res://Prefabs/Crafting/ItemDisplay.tscn");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Texture2D LoadPath(string path)
|
|
||||||
{
|
|
||||||
return GD.Load<Texture2D>(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<string, MeshInstance3D> LoadTiles()
|
|
||||||
{
|
|
||||||
Dictionary<string, MeshInstance3D> tileMeshes = new Dictionary<string, MeshInstance3D>();
|
|
||||||
PackedScene tileCollection = GD.Load<PackedScene>($"res://Assets/Objects/Tiles.glb");
|
|
||||||
Node root = tileCollection.Instantiate();
|
|
||||||
foreach (MeshInstance3D child in root.GetChildren())
|
|
||||||
{
|
|
||||||
tileMeshes.Add(child.Name.ToString().ToLower(), child);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tileMeshes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<string, MeshInstance3D> LoadDecorations()
|
|
||||||
{
|
|
||||||
Dictionary<string, MeshInstance3D> decorationMeshes = new Dictionary<string, MeshInstance3D>();
|
|
||||||
PackedScene decorationCollection = GD.Load<PackedScene>($"res://Assets/Objects/Decorations.glb");
|
|
||||||
Node root = decorationCollection.Instantiate();
|
|
||||||
foreach (MeshInstance3D child in root.GetChildren())
|
|
||||||
{
|
|
||||||
decorationMeshes.Add(child.Name.ToString().ToLower(), child);
|
|
||||||
}
|
|
||||||
|
|
||||||
return decorationMeshes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<ProgramNode, PackedScene> LoadDSLNodes()
|
|
||||||
{
|
|
||||||
Dictionary<ProgramNode, PackedScene> nodes = new()
|
|
||||||
{
|
|
||||||
{ new MoveNode(), GD.Load<PackedScene>($"res://Prefabs/DSL/MoveNode.tscn") },
|
|
||||||
{ new HarvestNode(), GD.Load<PackedScene>($"res://Prefabs/DSL/HarvestNode.tscn") },
|
|
||||||
{ new CraftNode(), GD.Load<PackedScene>($"res://Prefabs/DSL/CraftNode.tscn") },
|
|
||||||
{ new ExploreNode(), GD.Load<PackedScene>($"res://Prefabs/DSL/ExploreNode.tscn") }
|
|
||||||
};
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<string, Texture2D> LoadResourceSymbols()
|
|
||||||
{
|
|
||||||
Dictionary<string, Texture2D> symbols = new()
|
|
||||||
{
|
|
||||||
{ "iron_ore", GD.Load<Texture2D>($"res://Assets/Images/Resources/IronSymbol.png") },
|
|
||||||
{ "tin_ore", GD.Load<Texture2D>($"res://Assets/Images/Resources/TinSymbol.png") },
|
|
||||||
{ "copper_ore", GD.Load<Texture2D>($"res://Assets/Images/Resources/CopperSymbol.png") },
|
|
||||||
{ "mushroom", GD.Load<Texture2D>($"res://Assets/Images/Resources/MushroomSymbol.png") },
|
|
||||||
{ "spider_silk", GD.Load<Texture2D>($"res://Assets/Images/Resources/SpiderSilkSymbol.png") },
|
|
||||||
{ "coal", GD.Load<Texture2D>($"res://Assets/Images/Resources/CoalSymbol.png") },
|
|
||||||
{ "water", GD.Load<Texture2D>($"res://Assets/Images/Resources/WaterSymbol.png") },
|
|
||||||
{ "stone", GD.Load<Texture2D>($"res://Assets/Images/Resources/StoneSymbol.png") },
|
|
||||||
};
|
|
||||||
return symbols;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SortedDictionary<string, ItemData> LoadItems()
|
|
||||||
{
|
|
||||||
|
|
||||||
FileAccess file = FileAccess.Open("res://Assets/Recipes.json", FileAccess.ModeFlags.Read);
|
|
||||||
string json = file.GetAsText();
|
|
||||||
|
|
||||||
SortedDictionary<string, ItemData> result = new();
|
|
||||||
|
|
||||||
List<ItemData> items = JsonSerializer.Deserialize<List<ItemData>>(json);
|
|
||||||
foreach (ItemData item in items)
|
|
||||||
{
|
|
||||||
result.Add(item.Id, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<string, Research> LoadResearch()
|
|
||||||
{
|
|
||||||
|
|
||||||
FileAccess file = FileAccess.Open("res://Assets/Research.json", FileAccess.ModeFlags.Read);
|
|
||||||
string json = file.GetAsText();
|
|
||||||
|
|
||||||
Dictionary<string, Research> result = new();
|
|
||||||
|
|
||||||
List<ResearchData> researches = JsonSerializer.Deserialize<List<ResearchData>>(json);
|
|
||||||
foreach (ResearchData research in researches)
|
|
||||||
{
|
|
||||||
result.Add(research.Id, new Research(research));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
using Godot;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
public partial class MainMenu : Control
|
|
||||||
{
|
|
||||||
// Called when the node enters the scene tree for the first time.
|
|
||||||
public override void _Ready()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
||||||
public override void _Process(double delta)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPlayPressed()
|
|
||||||
{
|
|
||||||
GetTree().ChangeSceneToFile("res://Scenes/Game.tscn");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnQuitPressed()
|
|
||||||
{
|
|
||||||
GetTree().Quit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://pxegmc5nenad
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using Godot;
|
using Godot;
|
||||||
using static GameData;
|
using static GameData;
|
||||||
|
|
||||||
@@ -8,13 +7,9 @@ public partial class Camera3d : Camera3D
|
|||||||
[Export] public float MouseSensitivity = 0.2f;
|
[Export] public float MouseSensitivity = 0.2f;
|
||||||
[Export] public float ScrollStrength = 5.0f;
|
[Export] public float ScrollStrength = 5.0f;
|
||||||
|
|
||||||
private bool isShowingMap = false;
|
|
||||||
|
|
||||||
private Vector2 _mouseDelta;
|
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
Position = new Vector3(0, 0, tileWidth/2);
|
Position = new Vector3(0, 0, tileWidth / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
@@ -26,12 +21,10 @@ public partial class Camera3d : Camera3D
|
|||||||
{
|
{
|
||||||
float d = (float)delta;
|
float d = (float)delta;
|
||||||
|
|
||||||
var rotation = RotationDegrees;
|
Vector3 rotation = RotationDegrees;
|
||||||
rotation.X = Mathf.Clamp(rotation.X, -90f, 90f);
|
rotation.X = Mathf.Clamp(rotation.X, -90f, 90f);
|
||||||
RotationDegrees = rotation;
|
RotationDegrees = rotation;
|
||||||
|
|
||||||
_mouseDelta = Vector2.Zero;
|
|
||||||
|
|
||||||
Vector3 direction = Vector3.Zero;
|
Vector3 direction = Vector3.Zero;
|
||||||
if (Input.IsActionPressed("move_forward") && Position.Z > 0) direction += Transform.Basis.Z;
|
if (Input.IsActionPressed("move_forward") && Position.Z > 0) direction += Transform.Basis.Z;
|
||||||
if (Input.IsActionPressed("move_backward") && Position.Z < layerSize * 6) direction -= Transform.Basis.Z;
|
if (Input.IsActionPressed("move_backward") && Position.Z < layerSize * 6) direction -= Transform.Basis.Z;
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
public partial class UIHandler : Control
|
public partial class UIHandler : Control
|
||||||
@@ -19,27 +17,22 @@ public partial class UIHandler : Control
|
|||||||
[Export] ResearchList researchList;
|
[Export] ResearchList researchList;
|
||||||
[Export] TextureRect robotAlarm;
|
[Export] TextureRect robotAlarm;
|
||||||
|
|
||||||
bool receivedRobotJumpSignal = false;
|
private bool receivedRobotJumpSignal = false;
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
|
robotList.OnRobotJumpTo += OnRobotJumpTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _ExitTree()
|
||||||
|
{
|
||||||
|
robotList.OnRobotJumpTo -= OnRobotJumpTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
DisplayStats();
|
DisplayStats();
|
||||||
DisplayRobotAlarm();
|
DisplayRobotAlarm();
|
||||||
robotList.OnRobotJumpTo += (robot) =>
|
|
||||||
{
|
|
||||||
if(receivedRobotJumpSignal) return;
|
|
||||||
receivedRobotJumpSignal = true;
|
|
||||||
mainCam.Position = new Vector3(robot.Position.X, mainCam.Position.Y, robot.Position.Z + 3f);
|
|
||||||
codingWindow.SetRobot(robot);
|
|
||||||
OpenUIElement(codingWindow);
|
|
||||||
};
|
|
||||||
|
|
||||||
//Enable user to write in input fields
|
|
||||||
Control focused = GetViewport().GuiGetFocusOwner();
|
Control focused = GetViewport().GuiGetFocusOwner();
|
||||||
|
|
||||||
if (focused is LineEdit || focused is TextEdit)
|
if (focused is LineEdit || focused is TextEdit)
|
||||||
@@ -50,7 +43,6 @@ public partial class UIHandler : Control
|
|||||||
if (Input.IsActionJustPressed("robot_list")) HandleRobotListButton();
|
if (Input.IsActionJustPressed("robot_list")) HandleRobotListButton();
|
||||||
if (Input.IsActionJustPressed("inventory")) HandleInventoryButton();
|
if (Input.IsActionJustPressed("inventory")) HandleInventoryButton();
|
||||||
if (Input.IsActionJustPressed("research")) HandleResearchButton();
|
if (Input.IsActionJustPressed("research")) HandleResearchButton();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleMenuButton()
|
public void HandleMenuButton()
|
||||||
@@ -58,10 +50,20 @@ public partial class UIHandler : Control
|
|||||||
OpenUIElement(menu);
|
OpenUIElement(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void HandleMenu()
|
||||||
|
{
|
||||||
|
HandleMenuButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowOptions()
|
||||||
|
{
|
||||||
|
OpenUIElement(options);
|
||||||
|
}
|
||||||
|
|
||||||
public void HandleMapButton()
|
public void HandleMapButton()
|
||||||
{
|
{
|
||||||
OpenUIElement(map);
|
OpenUIElement(map);
|
||||||
if(map.Visible) map.ShowMap();
|
if (map.Visible) map.ShowMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleRobotListButton()
|
public void HandleRobotListButton()
|
||||||
@@ -78,7 +80,7 @@ public partial class UIHandler : Control
|
|||||||
public void HandleResearchButton()
|
public void HandleResearchButton()
|
||||||
{
|
{
|
||||||
OpenUIElement(researchList);
|
OpenUIElement(researchList);
|
||||||
if(researchList.Visible) researchList.SetupGraph();
|
if (researchList.Visible) researchList.SetupGraph();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DisplayStats()
|
public void DisplayStats()
|
||||||
@@ -121,15 +123,22 @@ public partial class UIHandler : Control
|
|||||||
string messages = "";
|
string messages = "";
|
||||||
foreach (Robot robot in GameData.robots)
|
foreach (Robot robot in GameData.robots)
|
||||||
{
|
{
|
||||||
if(robot.currentMessage.Length > 0)
|
if (robot.currentMessage.Length > 0)
|
||||||
{
|
{
|
||||||
messages += $"{robot.Name}: {robot.currentMessage}";
|
messages += $"{robot.Name}: {robot.currentMessage}\r";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
robotAlarm.Visible = messages.Length > 0;
|
robotAlarm.Visible = messages.Length > 0;
|
||||||
if (messages.Length >= 0)
|
robotAlarm.TooltipText = messages;
|
||||||
{
|
}
|
||||||
robotAlarm.TooltipText = messages;
|
|
||||||
}
|
private void OnRobotJumpTo(Robot robot)
|
||||||
|
{
|
||||||
|
if (receivedRobotJumpSignal) return;
|
||||||
|
|
||||||
|
receivedRobotJumpSignal = true;
|
||||||
|
mainCam.Position = new Vector3(robot.Position.X, mainCam.Position.Y, robot.Position.Z + 3f);
|
||||||
|
codingWindow.SetRobot(robot);
|
||||||
|
OpenUIElement(codingWindow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,34 +1,24 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
public partial class CodingWindow : PanelContainer
|
public partial class CodingWindow : PanelContainer
|
||||||
{
|
{
|
||||||
//General
|
private Robot robot;
|
||||||
Robot robot;
|
|
||||||
//Scripting
|
|
||||||
[Export] VBoxContainer codeBlocks;
|
[Export] VBoxContainer codeBlocks;
|
||||||
[Export] VBoxContainer editorWindow;
|
[Export] VBoxContainer editorWindow;
|
||||||
public Dictionary<ProgramNode, PackedScene> DSLNodes;
|
|
||||||
[Export] OptionButton availableScripts;
|
[Export] OptionButton availableScripts;
|
||||||
[Export] LineEdit scriptName;
|
[Export] LineEdit scriptName;
|
||||||
|
|
||||||
//Renaming
|
|
||||||
[Export] LineEdit nameInput;
|
[Export] LineEdit nameInput;
|
||||||
|
|
||||||
// Called when the node enters the scene tree for the first time.
|
public Dictionary<ProgramNode, PackedScene> DSLNodes;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
DSLNodes = ResourceLoader.LoadDSLNodes();
|
DSLNodes = ResourceLoader.LoadDSLNodes();
|
||||||
GenerateCodingBlocks();
|
GenerateCodingBlocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
||||||
public override void _Process(double delta)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void _Notification(int id)
|
public override void _Notification(int id)
|
||||||
{
|
{
|
||||||
if (id == NotificationVisibilityChanged)
|
if (id == NotificationVisibilityChanged)
|
||||||
@@ -39,6 +29,8 @@ public partial class CodingWindow : PanelContainer
|
|||||||
|
|
||||||
private void LoadWindow()
|
private void LoadWindow()
|
||||||
{
|
{
|
||||||
|
if (robot == null) return;
|
||||||
|
|
||||||
nameInput.Text = robot.Name;
|
nameInput.Text = robot.Name;
|
||||||
SetupScriptOptions();
|
SetupScriptOptions();
|
||||||
ClearWindow();
|
ClearWindow();
|
||||||
@@ -58,6 +50,8 @@ public partial class CodingWindow : PanelContainer
|
|||||||
|
|
||||||
public void SaveRobotName()
|
public void SaveRobotName()
|
||||||
{
|
{
|
||||||
|
if (robot == null) return;
|
||||||
|
|
||||||
robot.Name = nameInput.Text;
|
robot.Name = nameInput.Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,26 +63,32 @@ public partial class CodingWindow : PanelContainer
|
|||||||
public void GenerateCodingBlocks()
|
public void GenerateCodingBlocks()
|
||||||
{
|
{
|
||||||
NodeDisplay nodeDisplay;
|
NodeDisplay nodeDisplay;
|
||||||
foreach (ProgramNode node in DSLNodes.Keys)
|
foreach (ProgramNode nodeTemplate in DSLNodes.Keys)
|
||||||
{
|
{
|
||||||
nodeDisplay = DSLNodes[node].Instantiate<NodeDisplay>();
|
nodeDisplay = DSLNodes[nodeTemplate].Instantiate<NodeDisplay>();
|
||||||
nodeDisplay.node = node;
|
nodeDisplay.node = nodeTemplate;
|
||||||
codeBlocks.AddChild(nodeDisplay);
|
codeBlocks.AddChild(nodeDisplay);
|
||||||
nodeDisplay.ShowListDisplay();
|
nodeDisplay.ShowListDisplay();
|
||||||
nodeDisplay.listDisplay.Pressed += () =>
|
nodeDisplay.listDisplay.Pressed += () =>
|
||||||
{
|
{
|
||||||
NodeDisplay editorDisplay = DSLNodes[node].Instantiate<NodeDisplay>();
|
AddEditorNode(DSLNodes[nodeTemplate], nodeTemplate.Duplicate());
|
||||||
editorDisplay.node = node;
|
|
||||||
editorWindow.AddChild(editorDisplay);
|
|
||||||
editorDisplay.ShowEditorDisplay();
|
|
||||||
editorDisplay.OnDeleteNode += () =>
|
|
||||||
{
|
|
||||||
editorWindow.RemoveChild(editorDisplay);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddEditorNode(PackedScene prefab, ProgramNode node)
|
||||||
|
{
|
||||||
|
NodeDisplay editorDisplay = prefab.Instantiate<NodeDisplay>();
|
||||||
|
editorDisplay.node = node;
|
||||||
|
editorWindow.AddChild(editorDisplay);
|
||||||
|
editorDisplay.ShowEditorDisplay();
|
||||||
|
editorDisplay.OnDeleteNode += () =>
|
||||||
|
{
|
||||||
|
editorWindow.RemoveChild(editorDisplay);
|
||||||
|
editorDisplay.QueueFree();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public void ClearWindow()
|
public void ClearWindow()
|
||||||
{
|
{
|
||||||
foreach (Node node in editorWindow.GetChildren())
|
foreach (Node node in editorWindow.GetChildren())
|
||||||
@@ -105,14 +105,16 @@ public partial class CodingWindow : PanelContainer
|
|||||||
|
|
||||||
for (int i = 0; i < editorWindow.GetChildCount(); i++)
|
for (int i = 0; i < editorWindow.GetChildCount(); i++)
|
||||||
{
|
{
|
||||||
editorWindow.GetChild<NodeDisplay>(i).node.ReadParameters(editorWindow.GetChild<NodeDisplay>(i));
|
NodeDisplay nodeDisplay = editorWindow.GetChild<NodeDisplay>(i);
|
||||||
nodes.Add(editorWindow.GetChild<NodeDisplay>(i).node.Duplicate());
|
nodeDisplay.node.ReadParameters(nodeDisplay);
|
||||||
|
nodes.Add(nodeDisplay.node.Duplicate());
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
nodes[i - 1].nextNode = nodes[i];
|
nodes[i - 1].nextNode = nodes[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (robot == null) return;
|
||||||
if (nodes.Count > 0) robot.SetupExecution(nodes);
|
if (nodes.Count > 0) robot.SetupExecution(nodes);
|
||||||
robot.currentProgram = scriptName.Text.Length <= 0 ? $"Script{availableScripts.ItemCount}" : scriptName.Text;
|
robot.currentProgram = scriptName.Text.Length <= 0 ? $"Script{availableScripts.ItemCount}" : scriptName.Text;
|
||||||
}
|
}
|
||||||
@@ -137,6 +139,7 @@ public partial class CodingWindow : PanelContainer
|
|||||||
nodeDisplay.OnDeleteNode += () =>
|
nodeDisplay.OnDeleteNode += () =>
|
||||||
{
|
{
|
||||||
editorWindow.RemoveChild(nodeDisplay);
|
editorWindow.RemoveChild(nodeDisplay);
|
||||||
|
nodeDisplay.QueueFree();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,8 +152,9 @@ public partial class CodingWindow : PanelContainer
|
|||||||
string result = "";
|
string result = "";
|
||||||
for (int i = 0; i < editorWindow.GetChildCount(); i++)
|
for (int i = 0; i < editorWindow.GetChildCount(); i++)
|
||||||
{
|
{
|
||||||
editorWindow.GetChild<NodeDisplay>(i).node.ReadParameters(editorWindow.GetChild<NodeDisplay>(i));
|
NodeDisplay nodeDisplay = editorWindow.GetChild<NodeDisplay>(i);
|
||||||
result += editorWindow.GetChild<NodeDisplay>(i).node.Save();
|
nodeDisplay.node.ReadParameters(nodeDisplay);
|
||||||
|
result += nodeDisplay.node.Save();
|
||||||
result += ";\r\n";
|
result += ";\r\n";
|
||||||
}
|
}
|
||||||
if (result.Length <= 0) return;
|
if (result.Length <= 0) return;
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
@@ -18,14 +17,11 @@ public partial class NodeDisplay : PanelContainer
|
|||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
|
if (node == null) return;
|
||||||
|
|
||||||
node.Setup(this);
|
node.Setup(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _Process(double delta)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ShowListDisplay()
|
public void ShowListDisplay()
|
||||||
{
|
{
|
||||||
editorDisplay.Visible = false;
|
editorDisplay.Visible = false;
|
||||||
@@ -45,54 +41,56 @@ public partial class NodeDisplay : PanelContainer
|
|||||||
|
|
||||||
public static NodeDisplay Load(string content, Dictionary<ProgramNode, PackedScene> DSLNodes)
|
public static NodeDisplay Load(string content, Dictionary<ProgramNode, PackedScene> DSLNodes)
|
||||||
{
|
{
|
||||||
NodeDisplay result = null;
|
string nodeSanitized = content.Replace("\r\n", "").Trim();
|
||||||
ProgramNode program;
|
if (nodeSanitized.Length <= 0) return null;
|
||||||
string nodeName;
|
|
||||||
string nodeSanitized;
|
string nodeName = nodeSanitized.Split(",")[0].Replace("Name: ", "").ToLower();
|
||||||
PackedScene prefab = null;
|
PackedScene prefab = GetPrefab(nodeName, DSLNodes);
|
||||||
nodeSanitized = content.Replace("\r\n", "");
|
if (prefab == null) return null;
|
||||||
nodeName = nodeSanitized.Split(",")[0].Replace("Name: ", "").ToLower();
|
|
||||||
|
NodeDisplay result = prefab.Instantiate<NodeDisplay>();
|
||||||
|
|
||||||
|
switch (nodeName)
|
||||||
|
{
|
||||||
|
case "move":
|
||||||
|
result.node = new MoveNode();
|
||||||
|
result.LoadMove(nodeSanitized);
|
||||||
|
break;
|
||||||
|
case "harvest":
|
||||||
|
result.node = new HarvestNode();
|
||||||
|
result.LoadHarvest(nodeSanitized);
|
||||||
|
break;
|
||||||
|
case "explore":
|
||||||
|
result.node = new ExploreNode();
|
||||||
|
result.LoadExplore(nodeSanitized);
|
||||||
|
break;
|
||||||
|
case "craft":
|
||||||
|
result.node = new CraftNode();
|
||||||
|
result.LoadCraft(nodeSanitized);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result.QueueFree();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PackedScene GetPrefab(string nodeName, Dictionary<ProgramNode, PackedScene> DSLNodes)
|
||||||
|
{
|
||||||
foreach (ProgramNode programNode in DSLNodes.Keys)
|
foreach (ProgramNode programNode in DSLNodes.Keys)
|
||||||
{
|
{
|
||||||
if (programNode.DisplayText.ToLower() == nodeName)
|
if (programNode.DisplayText.ToLower() == nodeName)
|
||||||
{
|
{
|
||||||
prefab = DSLNodes[programNode];
|
return DSLNodes[programNode];
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (nodeName)
|
|
||||||
{
|
return null;
|
||||||
case "move":
|
|
||||||
program = new MoveNode();
|
|
||||||
result = prefab.Instantiate<NodeDisplay>();
|
|
||||||
result.node = program;
|
|
||||||
result.LoadMove(nodeSanitized);
|
|
||||||
break;
|
|
||||||
case "harvest":
|
|
||||||
program = new HarvestNode();
|
|
||||||
result = prefab.Instantiate<NodeDisplay>();
|
|
||||||
result.node = program;
|
|
||||||
result.LoadHarvest(nodeSanitized);
|
|
||||||
break;
|
|
||||||
case "explore":
|
|
||||||
program = new ExploreNode();
|
|
||||||
result = prefab.Instantiate<NodeDisplay>();
|
|
||||||
result.node = program;
|
|
||||||
result.LoadExplore(nodeSanitized);
|
|
||||||
break;
|
|
||||||
case "craft":
|
|
||||||
program = new CraftNode();
|
|
||||||
result = prefab.Instantiate<NodeDisplay>();
|
|
||||||
result.node = program;
|
|
||||||
result.LoadCraft(nodeSanitized);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadHarvest(string content)
|
public void LoadHarvest(string content)
|
||||||
{
|
{
|
||||||
//Currently does nothing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadMove(string content)
|
public void LoadMove(string content)
|
||||||
@@ -107,12 +105,15 @@ public partial class NodeDisplay : PanelContainer
|
|||||||
valueContainer.GetNode<SpinBox>("./CoordinateY").Value = posY;
|
valueContainer.GetNode<SpinBox>("./CoordinateY").Value = posY;
|
||||||
valueContainer.GetNode<SpinBox>("./CoordinateZ").Value = posZ;
|
valueContainer.GetNode<SpinBox>("./CoordinateZ").Value = posZ;
|
||||||
|
|
||||||
(node as MoveNode).targetPosition = new Vector3I(posX, posY, posZ);
|
MoveNode moveNode = node as MoveNode;
|
||||||
|
if (moveNode != null)
|
||||||
|
{
|
||||||
|
moveNode.targetPosition = new Vector3I(posX, posY, posZ);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadExplore(string content)
|
public void LoadExplore(string content)
|
||||||
{
|
{
|
||||||
//Currently does nothing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadCraft(string content)
|
public void LoadCraft(string content)
|
||||||
@@ -122,7 +123,11 @@ public partial class NodeDisplay : PanelContainer
|
|||||||
string itemString = parts[1].Replace("Item: ", "").Replace(" ", "");
|
string itemString = parts[1].Replace("Item: ", "").Replace(" ", "");
|
||||||
if (itemString.ToLower() != "empty")
|
if (itemString.ToLower() != "empty")
|
||||||
{
|
{
|
||||||
(node as CraftNode).selectedItem = new Item { data = GameData.availableItems[itemString] };
|
CraftNode craftNode = node as CraftNode;
|
||||||
|
if (craftNode != null)
|
||||||
|
{
|
||||||
|
craftNode.selectedItem = new Item { data = GameData.availableItems[itemString] };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
string amountString = parts[2].Replace("Amount: ", "");
|
string amountString = parts[2].Replace("Amount: ", "");
|
||||||
valueContainer.GetNode<SpinBox>("./Amount").Value = int.Parse(amountString);
|
valueContainer.GetNode<SpinBox>("./Amount").Value = int.Parse(amountString);
|
||||||
@@ -3,7 +3,7 @@ using Godot;
|
|||||||
|
|
||||||
public partial class InventoryDisplay : PanelContainer
|
public partial class InventoryDisplay : PanelContainer
|
||||||
{
|
{
|
||||||
PackedScene itemDisplayPrefab = ResourceLoader.LoadItemDisplay();
|
private PackedScene itemDisplayPrefab = ResourceLoader.LoadItemDisplay();
|
||||||
[Export] VBoxContainer itemList;
|
[Export] VBoxContainer itemList;
|
||||||
[Export] RichTextLabel inventorySpace;
|
[Export] RichTextLabel inventorySpace;
|
||||||
|
|
||||||
@@ -12,12 +12,19 @@ public partial class InventoryDisplay : PanelContainer
|
|||||||
GameData.inventory.OnInventoryUpdate += OnInventoryUpdate;
|
GameData.inventory.OnInventoryUpdate += OnInventoryUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void _ExitTree()
|
||||||
|
{
|
||||||
|
GameData.inventory.OnInventoryUpdate -= OnInventoryUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
public override void _Notification(int id)
|
public override void _Notification(int id)
|
||||||
{
|
{
|
||||||
if (id == NotificationVisibilityChanged)
|
if (id == NotificationVisibilityChanged)
|
||||||
{
|
{
|
||||||
if (Visible) ReloadItems();
|
if (!Visible) return;
|
||||||
if (Visible) UpdateInventorySpace();
|
|
||||||
|
ReloadItems();
|
||||||
|
UpdateInventorySpace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,6 +40,7 @@ public partial class InventoryDisplay : PanelContainer
|
|||||||
itemList.RemoveChild(node);
|
itemList.RemoveChild(node);
|
||||||
node.QueueFree();
|
node.QueueFree();
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemDisplay display;
|
ItemDisplay display;
|
||||||
|
|
||||||
foreach (Item item in GameData.inventory.items)
|
foreach (Item item in GameData.inventory.items)
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
public partial class ItemDisplay : PanelContainer
|
||||||
|
{
|
||||||
|
[Export] public TextureRect texture;
|
||||||
|
[Export] public RichTextLabel text;
|
||||||
|
[Export] public RichTextLabel amount;
|
||||||
|
public Item item;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
public partial class MainMenu : Control
|
||||||
|
{
|
||||||
|
public void OnPlayPressed()
|
||||||
|
{
|
||||||
|
GetTree().ChangeSceneToFile("res://Scenes/Game.tscn");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnQuitPressed()
|
||||||
|
{
|
||||||
|
GetTree().Quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Godot;
|
using Godot;
|
||||||
using Godot.Collections;
|
using Godot.Collections;
|
||||||
|
|
||||||
@@ -7,17 +5,14 @@ public partial class ResearchList : PanelContainer
|
|||||||
{
|
{
|
||||||
[Export] private GraphEdit researchGraph;
|
[Export] private GraphEdit researchGraph;
|
||||||
|
|
||||||
private List<string> reloadKeys = new List<string>();
|
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
RecalculateResearchStates();
|
RecalculateResearchStates();
|
||||||
if(Visible) SetupGraph();
|
if (Visible) SetupGraph();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetupGraph()
|
public void SetupGraph()
|
||||||
{
|
{
|
||||||
reloadKeys = new List<string>();
|
|
||||||
ClearGraph();
|
ClearGraph();
|
||||||
CreateResearchNodes();
|
CreateResearchNodes();
|
||||||
CreateResearchConnections();
|
CreateResearchConnections();
|
||||||
@@ -67,11 +62,9 @@ public partial class ResearchList : PanelContainer
|
|||||||
string prerequisite = research.data.Research;
|
string prerequisite = research.data.Research;
|
||||||
string current = research.data.Id;
|
string current = research.data.Id;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(prerequisite))
|
if (string.IsNullOrEmpty(prerequisite)) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!researchGraph.HasNode(prerequisite) || !researchGraph.HasNode(current))
|
if (!researchGraph.HasNode(prerequisite) || !researchGraph.HasNode(current)) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
researchGraph.ConnectNode(
|
researchGraph.ConnectNode(
|
||||||
prerequisite,
|
prerequisite,
|
||||||
@@ -135,46 +128,44 @@ public partial class ResearchList : PanelContainer
|
|||||||
|
|
||||||
private void RecalculateResearchStates()
|
private void RecalculateResearchStates()
|
||||||
{
|
{
|
||||||
bool changedState;
|
bool changedState = true;
|
||||||
foreach (string key in GameData.availableResearch.Keys)
|
|
||||||
|
while (changedState)
|
||||||
{
|
{
|
||||||
changedState = false;
|
changedState = false;
|
||||||
if (reloadKeys.Contains(key)) continue;
|
|
||||||
reloadKeys.Add(key);
|
|
||||||
|
|
||||||
//Already researched
|
foreach (Research research in GameData.availableResearch.Values)
|
||||||
if (GameData.availableResearch[key].state == ResearchState.RESEARCHED)
|
|
||||||
{
|
{
|
||||||
|
ResearchState newState = GetUpdatedResearchState(research);
|
||||||
|
|
||||||
|
if (research.state == newState) continue;
|
||||||
|
|
||||||
|
research.state = newState;
|
||||||
changedState = true;
|
changedState = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//No previous research needed
|
|
||||||
if (GameData.availableResearch[key].data.Research.Length <= 0)
|
|
||||||
{
|
|
||||||
GameData.availableResearch[key].state = ResearchState.RESEARCHED;
|
|
||||||
changedState = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Previous research is unlocked
|
|
||||||
if (!changedState && GameData.availableResearch[GameData.availableResearch[key].data.Research].state == ResearchState.RESEARCHED)
|
|
||||||
{
|
|
||||||
GameData.availableResearch[key].state = ResearchState.AVAILABLE;
|
|
||||||
changedState = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!changedState)
|
|
||||||
{
|
|
||||||
//All others are locked
|
|
||||||
GameData.availableResearch[key].state = ResearchState.LOCKED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reloadKeys.Count != GameData.availableResearch.Keys.Count)
|
|
||||||
{
|
|
||||||
RecalculateResearchStates();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ResearchState GetUpdatedResearchState(Research research)
|
||||||
|
{
|
||||||
|
if (research.state == ResearchState.RESEARCHED)
|
||||||
|
{
|
||||||
|
return ResearchState.RESEARCHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (research.data.Research.Length <= 0)
|
||||||
|
{
|
||||||
|
return ResearchState.RESEARCHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GameData.availableResearch[research.data.Research].state == ResearchState.RESEARCHED)
|
||||||
|
{
|
||||||
|
return ResearchState.AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResearchState.LOCKED;
|
||||||
|
}
|
||||||
|
|
||||||
private Color GetColorByState(ResearchState state)
|
private Color GetColorByState(ResearchState state)
|
||||||
{
|
{
|
||||||
return state switch
|
return state switch
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
public partial class RobotDisplay : PanelContainer
|
public partial class RobotDisplay : PanelContainer
|
||||||
@@ -8,16 +7,13 @@ public partial class RobotDisplay : PanelContainer
|
|||||||
[Signal]
|
[Signal]
|
||||||
public delegate void OnRobotJumpToEventHandler(Robot robot);
|
public delegate void OnRobotJumpToEventHandler(Robot robot);
|
||||||
public Robot robot;
|
public Robot robot;
|
||||||
public override void _Ready()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
if (robot.currentProgram != currentScript.Text)
|
string programName = robot.currentProgram ?? "";
|
||||||
|
if (programName != currentScript.Text)
|
||||||
{
|
{
|
||||||
currentScript.Text = robot.currentProgram;
|
currentScript.Text = programName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,24 +1,17 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
using System;
|
|
||||||
|
|
||||||
public partial class RobotList : PanelContainer
|
public partial class RobotList : PanelContainer
|
||||||
{
|
{
|
||||||
[Export] VBoxContainer robotList;
|
[Export] VBoxContainer robotList;
|
||||||
[Signal]
|
[Signal]
|
||||||
public delegate void OnRobotJumpToEventHandler(Robot robot);
|
public delegate void OnRobotJumpToEventHandler(Robot robot);
|
||||||
public PackedScene robotDisplayPrefab;
|
private PackedScene robotDisplayPrefab;
|
||||||
// Called when the node enters the scene tree for the first time.
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
robotDisplayPrefab = ResourceLoader.LoadRobotDisplay();
|
robotDisplayPrefab = ResourceLoader.LoadRobotDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
||||||
public override void _Process(double delta)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void _Notification(int id)
|
public override void _Notification(int id)
|
||||||
{
|
{
|
||||||
if (id == NotificationVisibilityChanged)
|
if (id == NotificationVisibilityChanged)
|
||||||
@@ -1,25 +1,25 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using static WFC;
|
using static WFC;
|
||||||
|
|
||||||
public partial class Layer : Node3D
|
public partial class Layer : Node3D
|
||||||
{
|
{
|
||||||
|
private const int MaxGenerationAttempts = 1000;
|
||||||
|
private static readonly Vector2I NoPosition = new Vector2I(-100, -100);
|
||||||
|
|
||||||
private Node3D decorationRoot;
|
private Node3D decorationRoot;
|
||||||
public Tile[,] tiles;
|
public Tile[,] tiles;
|
||||||
int layerSize;
|
private int layerSize;
|
||||||
Tile tile;
|
private int level;
|
||||||
int level;
|
private bool updateFailed = false;
|
||||||
bool updateFailed = false;
|
|
||||||
public bool hasContentGenerated = false;
|
public bool hasContentGenerated = false;
|
||||||
public Vector2I gateCoordinate;
|
public Vector2I gateCoordinate;
|
||||||
public List<string> currentResources;
|
public List<string> currentResources;
|
||||||
public bool isGateOpen = false;
|
public bool isGateOpen = false;
|
||||||
|
|
||||||
// Called when the node enters the scene tree for the first time.
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
currentResources = new();
|
currentResources = new List<string>();
|
||||||
decorationRoot = new Node3D
|
decorationRoot = new Node3D
|
||||||
{
|
{
|
||||||
Name = "Decorations"
|
Name = "Decorations"
|
||||||
@@ -27,15 +27,9 @@ public partial class Layer : Node3D
|
|||||||
AddChild(decorationRoot);
|
AddChild(decorationRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
||||||
public override void _Process(double delta)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearDecorations()
|
public void ClearDecorations()
|
||||||
{
|
{
|
||||||
foreach (var tile in tiles)
|
foreach (Tile tile in tiles)
|
||||||
{
|
{
|
||||||
foreach (Node child in tile.ContentNode.GetChildren())
|
foreach (Node child in tile.ContentNode.GetChildren())
|
||||||
{
|
{
|
||||||
@@ -49,14 +43,16 @@ public partial class Layer : Node3D
|
|||||||
this.layerSize = layerSize;
|
this.layerSize = layerSize;
|
||||||
this.level = level;
|
this.level = level;
|
||||||
tiles = new Tile[layerSize, layerSize];
|
tiles = new Tile[layerSize, layerSize];
|
||||||
|
|
||||||
GenerateBaseStructure(tileMeshes);
|
GenerateBaseStructure(tileMeshes);
|
||||||
|
|
||||||
int safetyCounter = 0;
|
int safetyCounter = 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (GenerateLayer(collapseOrigin)) break;
|
if (GenerateLayer(collapseOrigin)) break;
|
||||||
ResetLayer(tileMeshes);
|
ResetLayer(tileMeshes);
|
||||||
safetyCounter++;
|
safetyCounter++;
|
||||||
if (safetyCounter > 1000) break;
|
if (safetyCounter > MaxGenerationAttempts) break;
|
||||||
}
|
}
|
||||||
CreateTileNodes();
|
CreateTileNodes();
|
||||||
}
|
}
|
||||||
@@ -74,7 +70,7 @@ public partial class Layer : Node3D
|
|||||||
{
|
{
|
||||||
offsetZ = y * GameData.tileWidth;
|
offsetZ = y * GameData.tileWidth;
|
||||||
position = new Vector3(offsetX, offsetY, offsetZ);
|
position = new Vector3(offsetX, offsetY, offsetZ);
|
||||||
tile = new Tile();
|
Tile tile = new Tile();
|
||||||
tile.SetMeshes(tileMeshes);
|
tile.SetMeshes(tileMeshes);
|
||||||
tile.Position = position;
|
tile.Position = position;
|
||||||
tile.GridPosition = new Vector2I(x, y);
|
tile.GridPosition = new Vector2I(x, y);
|
||||||
@@ -85,9 +81,9 @@ public partial class Layer : Node3D
|
|||||||
|
|
||||||
private void CreateTileNodes()
|
private void CreateTileNodes()
|
||||||
{
|
{
|
||||||
foreach (var tile in tiles)
|
foreach (Tile tile in tiles)
|
||||||
{
|
{
|
||||||
var node = new Node3D
|
Node3D node = new Node3D
|
||||||
{
|
{
|
||||||
Position = tile.Position,
|
Position = tile.Position,
|
||||||
Visible = tile.collapsedMesh != null && tile.collapsedMesh == "gate"
|
Visible = tile.collapsedMesh != null && tile.collapsedMesh == "gate"
|
||||||
@@ -100,6 +96,8 @@ public partial class Layer : Node3D
|
|||||||
|
|
||||||
private void ResetLayer(Dictionary<string, MeshInstance3D> tileMeshes)
|
private void ResetLayer(Dictionary<string, MeshInstance3D> tileMeshes)
|
||||||
{
|
{
|
||||||
|
updateFailed = false;
|
||||||
|
|
||||||
for (int x = 0; x < layerSize; x++)
|
for (int x = 0; x < layerSize; x++)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < layerSize; y++)
|
for (int y = 0; y < layerSize; y++)
|
||||||
@@ -115,13 +113,12 @@ public partial class Layer : Node3D
|
|||||||
{
|
{
|
||||||
for (int z = 0; z < layerSize; z++)
|
for (int z = 0; z < layerSize; z++)
|
||||||
{
|
{
|
||||||
//Exclude spawn from border generation
|
if (x == 0 && z == 0 && level == 0) continue;
|
||||||
if(x == 0 && z == 0 && level == 0) continue;
|
|
||||||
if (!IsBorder(x, z))
|
if (!IsBorder(x, z))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var tile = tiles[x, z];
|
Tile tile = tiles[x, z];
|
||||||
var possibilities = GetBorderPossibilities(x, z);
|
List<string> possibilities = GetBorderPossibilities(x, z);
|
||||||
|
|
||||||
if (possibilities.Count == 0)
|
if (possibilities.Count == 0)
|
||||||
continue;
|
continue;
|
||||||
@@ -142,10 +139,10 @@ public partial class Layer : Node3D
|
|||||||
//Generate spawn only in the first layer
|
//Generate spawn only in the first layer
|
||||||
if (level == 0)
|
if (level == 0)
|
||||||
{
|
{
|
||||||
tiles[0,0].Collapse("spawn");
|
tiles[0, 0].Collapse("spawn");
|
||||||
Propagate(new Vector2I());
|
Propagate(new Vector2I());
|
||||||
}
|
}
|
||||||
//Randomly position the gate to the next layer
|
|
||||||
int posX, posY;
|
int posX, posY;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@@ -162,13 +159,10 @@ public partial class Layer : Node3D
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool GenerateLayer(Vector2I collapseOrigin)
|
public bool GenerateLayer(Vector2I collapseOrigin)
|
||||||
{
|
{
|
||||||
bool result = true;
|
|
||||||
int safetyCounter = 0;
|
int safetyCounter = 0;
|
||||||
GenerateBorder();
|
GenerateBorder();
|
||||||
|
|
||||||
@@ -183,7 +177,7 @@ public partial class Layer : Node3D
|
|||||||
Propagate(position);
|
Propagate(position);
|
||||||
if (updateFailed) break;
|
if (updateFailed) break;
|
||||||
position = GetSmallestPossibilities();
|
position = GetSmallestPossibilities();
|
||||||
if (position == new Vector2(-100, -100))
|
if (position == NoPosition)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -193,10 +187,8 @@ public partial class Layer : Node3D
|
|||||||
if (safetyCounter == layerSize * layerSize) return false;
|
if (safetyCounter == layerSize * layerSize) return false;
|
||||||
}
|
}
|
||||||
if (updateFailed) return false;
|
if (updateFailed) return false;
|
||||||
//Player has over 80% of tiles available without destroying walls => Results in about 95% success rate
|
|
||||||
//Not necessarily needed but improves the overall generation percentage at a low resource cost
|
|
||||||
if (!WFC.IsMapConnected(tiles, 0.8f)) return false;
|
if (!WFC.IsMapConnected(tiles, 0.8f)) return false;
|
||||||
return result;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Propagate(Vector2I startPos)
|
private void Propagate(Vector2I startPos)
|
||||||
@@ -209,8 +201,7 @@ public partial class Layer : Node3D
|
|||||||
Vector2I currentPos = queue.Dequeue();
|
Vector2I currentPos = queue.Dequeue();
|
||||||
Tile currentTile = tiles[currentPos.X, currentPos.Y];
|
Tile currentTile = tiles[currentPos.X, currentPos.Y];
|
||||||
|
|
||||||
// Use CURRENT state of tile
|
HashSet<string> currentPossibilities = currentTile.collapsedMesh != null
|
||||||
var currentPossibilities = currentTile.collapsedMesh != null
|
|
||||||
? new HashSet<string> { currentTile.collapsedMesh }
|
? new HashSet<string> { currentTile.collapsedMesh }
|
||||||
: new HashSet<string>(currentTile.tileMeshes.Keys);
|
: new HashSet<string>(currentTile.tileMeshes.Keys);
|
||||||
|
|
||||||
@@ -243,7 +234,6 @@ public partial class Layer : Node3D
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ONLY enqueue if something changed
|
|
||||||
if (updateCount > 0)
|
if (updateCount > 0)
|
||||||
{
|
{
|
||||||
queue.Enqueue(newPos);
|
queue.Enqueue(newPos);
|
||||||
@@ -255,7 +245,7 @@ public partial class Layer : Node3D
|
|||||||
|
|
||||||
private Vector2I GetSmallestPossibilities()
|
private Vector2I GetSmallestPossibilities()
|
||||||
{
|
{
|
||||||
Vector2I result = new Vector2I(-100, -100);
|
Vector2I result = NoPosition;
|
||||||
int lowest = 100;
|
int lowest = 100;
|
||||||
int current;
|
int current;
|
||||||
for (int x = 0; x < layerSize; x++)
|
for (int x = 0; x < layerSize; x++)
|
||||||
@@ -3,12 +3,13 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
public class LightHandler
|
public class LightHandler
|
||||||
{
|
{
|
||||||
public static List<OmniLight3D> lights = new ();
|
public static List<OmniLight3D> lights = new List<OmniLight3D>();
|
||||||
|
|
||||||
public static void RedrawLights(Color color)
|
public static void RedrawLights(Color color)
|
||||||
{
|
{
|
||||||
List<OmniLight3D> availableLights = new();
|
List<OmniLight3D> availableLights = new List<OmniLight3D>();
|
||||||
foreach(OmniLight3D light in lights)
|
|
||||||
|
foreach (OmniLight3D light in lights)
|
||||||
{
|
{
|
||||||
if (GodotObject.IsInstanceValid(light))
|
if (GodotObject.IsInstanceValid(light))
|
||||||
{
|
{
|
||||||
@@ -16,6 +17,7 @@ public class LightHandler
|
|||||||
availableLights.Add(light);
|
availableLights.Add(light);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lights = [..availableLights];
|
|
||||||
|
lights = availableLights;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,79 +7,32 @@ public partial class Map : PanelContainer
|
|||||||
[Export] GridContainer grid;
|
[Export] GridContainer grid;
|
||||||
private HashSet<Tile> handledTiles = new HashSet<Tile>();
|
private HashSet<Tile> handledTiles = new HashSet<Tile>();
|
||||||
private Dictionary<Tile, TextureRect> textureMap = new Dictionary<Tile, TextureRect>();
|
private Dictionary<Tile, TextureRect> textureMap = new Dictionary<Tile, TextureRect>();
|
||||||
// Called when the node enters the scene tree for the first time.
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
grid.Columns = GameData.layerSize + 1;
|
grid.Columns = GameData.layerSize + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
||||||
public override void _Process(double delta)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ShowMap()
|
public void ShowMap()
|
||||||
{
|
{
|
||||||
if (!Visible) return;
|
if (!Visible) return;
|
||||||
foreach (Node node in grid.GetChildren())
|
|
||||||
{
|
ClearGrid();
|
||||||
grid.RemoveChild(node);
|
|
||||||
node.QueueFree();
|
|
||||||
}
|
|
||||||
TextureRect texture;
|
|
||||||
Label label;
|
|
||||||
Tile[,] tiles = GameData.map[GameData.currentLayer].tiles;
|
Tile[,] tiles = GameData.map[GameData.currentLayer].tiles;
|
||||||
int size = GameData.layerSize;
|
int size = GameData.layerSize;
|
||||||
|
|
||||||
for (int z = -1; z < size; z++)
|
for (int z = -1; z < size; z++)
|
||||||
{
|
{
|
||||||
for (int x = -1; x < size; x++)
|
for (int x = -1; x < size; x++)
|
||||||
{
|
{
|
||||||
if (z == -1 || x == -1)
|
if (z == -1 || x == -1)
|
||||||
{
|
{
|
||||||
label = new Label
|
grid.AddChild(CreateHeaderLabel(x, z));
|
||||||
{
|
|
||||||
HorizontalAlignment = HorizontalAlignment.Center,
|
|
||||||
VerticalAlignment = VerticalAlignment.Center,
|
|
||||||
|
|
||||||
SizeFlagsHorizontal = SizeFlags.ExpandFill,
|
|
||||||
SizeFlagsVertical = SizeFlags.ExpandFill
|
|
||||||
};
|
|
||||||
if (z == -1 && x == -1)
|
|
||||||
{
|
|
||||||
label.Text = "\u2193 Z | \u2192 X";
|
|
||||||
}
|
|
||||||
else if (z == -1)
|
|
||||||
{
|
|
||||||
label.Text = x.ToString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
label.Text = z.ToString();
|
|
||||||
}
|
|
||||||
grid.AddChild(label);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
texture = new TextureRect();
|
|
||||||
if (tiles[x, z].wasVisited || GameData.DEBUGMODE)
|
|
||||||
{
|
|
||||||
if (tiles[x, z].containsResource)
|
|
||||||
{
|
|
||||||
texture.Texture = ResourceDistributor.resources[tiles[x, z].resource.name];
|
|
||||||
texture.TooltipText = tiles[x, z].resource.item.GetReadableName() + $"\r(X: {x},Y: {GameData.currentLayer},Z: {z})";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
texture.Texture = GenerateTexture(32, new Color(0, 0, 0, 0));
|
|
||||||
texture.TooltipText = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
texture.Texture = GenerateTexture(32, new Color(0, 0, 0, 1));
|
|
||||||
texture.TooltipText = "Not explored";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
TextureRect texture = CreateTileTexture(tiles[x, z]);
|
||||||
textureMap[tiles[x, z]] = texture;
|
textureMap[tiles[x, z]] = texture;
|
||||||
|
|
||||||
if (!handledTiles.Contains(tiles[x, z]))
|
if (!handledTiles.Contains(tiles[x, z]))
|
||||||
@@ -93,11 +46,49 @@ public partial class Map : PanelContainer
|
|||||||
texture.StretchMode = TextureRect.StretchModeEnum.Scale;
|
texture.StretchMode = TextureRect.StretchModeEnum.Scale;
|
||||||
|
|
||||||
grid.AddChild(texture);
|
grid.AddChild(texture);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ClearGrid()
|
||||||
|
{
|
||||||
|
foreach (Node node in grid.GetChildren())
|
||||||
|
{
|
||||||
|
grid.RemoveChild(node);
|
||||||
|
node.QueueFree();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Label CreateHeaderLabel(int x, int z)
|
||||||
|
{
|
||||||
|
Label label = new Label
|
||||||
|
{
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
||||||
|
VerticalAlignment = VerticalAlignment.Center,
|
||||||
|
SizeFlagsHorizontal = SizeFlags.ExpandFill,
|
||||||
|
SizeFlagsVertical = SizeFlags.ExpandFill
|
||||||
|
};
|
||||||
|
|
||||||
|
if (z == -1 && x == -1) label.Text = "\u2193 Z | \u2192 X";
|
||||||
|
else if (z == -1) label.Text = x.ToString();
|
||||||
|
else label.Text = z.ToString();
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextureRect CreateTileTexture(Tile tile)
|
||||||
|
{
|
||||||
|
TextureRect texture = new TextureRect
|
||||||
|
{
|
||||||
|
SizeFlagsHorizontal = SizeFlags.ExpandFill,
|
||||||
|
SizeFlagsVertical = SizeFlags.ExpandFill,
|
||||||
|
StretchMode = TextureRect.StretchModeEnum.Scale
|
||||||
|
};
|
||||||
|
|
||||||
|
UpdateTileTexture(tile, texture);
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnTileVisited(object sender, EventArgs e)
|
private void OnTileVisited(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Tile tile = sender as Tile;
|
Tile tile = sender as Tile;
|
||||||
@@ -115,7 +106,17 @@ public partial class Map : PanelContainer
|
|||||||
{
|
{
|
||||||
if (!IsInstanceValid(texture)) return;
|
if (!IsInstanceValid(texture)) return;
|
||||||
|
|
||||||
if (tile.containsResource)
|
UpdateTileTexture(tile, texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateTileTexture(Tile tile, TextureRect texture)
|
||||||
|
{
|
||||||
|
if (!tile.wasVisited && !GameData.debugMode)
|
||||||
|
{
|
||||||
|
texture.Texture = GenerateTexture(32, new Color(0, 0, 0, 1));
|
||||||
|
texture.TooltipText = "Not explored";
|
||||||
|
}
|
||||||
|
else if (tile.containsResource)
|
||||||
{
|
{
|
||||||
texture.Texture = ResourceDistributor.resources[tile.resource.name];
|
texture.Texture = ResourceDistributor.resources[tile.resource.name];
|
||||||
texture.TooltipText = tile.resource.item.GetReadableName() + $"\r(X: {tile.GridPosition.X},Y: {GameData.currentLayer},Z: {tile.GridPosition.Y})";
|
texture.TooltipText = tile.resource.item.GetReadableName() + $"\r(X: {tile.GridPosition.X},Y: {GameData.currentLayer},Z: {tile.GridPosition.Y})";
|
||||||
@@ -129,9 +130,7 @@ public partial class Map : PanelContainer
|
|||||||
|
|
||||||
public Texture2D GenerateTexture(int size, Color fillColor)
|
public Texture2D GenerateTexture(int size, Color fillColor)
|
||||||
{
|
{
|
||||||
|
|
||||||
Image image = Image.CreateEmpty(size, size, false, Image.Format.Rgba8);
|
Image image = Image.CreateEmpty(size, size, false, Image.Format.Rgba8);
|
||||||
|
|
||||||
image.Fill(fillColor);
|
image.Fill(fillColor);
|
||||||
|
|
||||||
return ImageTexture.CreateFromImage(image);
|
return ImageTexture.CreateFromImage(image);
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public class MultiMeshHandler
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, MultiMeshInstance3D> multiMeshes;
|
||||||
|
|
||||||
|
public MultiMeshHandler(Dictionary<string, MultiMeshInstance3D> multiMeshes)
|
||||||
|
{
|
||||||
|
this.multiMeshes = multiMeshes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Build(List<TileRenderData> tiles)
|
||||||
|
{
|
||||||
|
foreach (MultiMeshInstance3D multiMeshInstance in multiMeshes.Values)
|
||||||
|
{
|
||||||
|
multiMeshInstance.Multimesh.InstanceCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<string, List<Transform3D>> batches = new Dictionary<string, List<Transform3D>>();
|
||||||
|
|
||||||
|
foreach (TileRenderData tile in tiles)
|
||||||
|
{
|
||||||
|
if (!batches.ContainsKey(tile.MeshKey))
|
||||||
|
{
|
||||||
|
batches[tile.MeshKey] = new List<Transform3D>();
|
||||||
|
}
|
||||||
|
|
||||||
|
batches[tile.MeshKey].Add(tile.Transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, List<Transform3D>> kvp in batches)
|
||||||
|
{
|
||||||
|
MultiMesh multiMesh = multiMeshes[kvp.Key].Multimesh;
|
||||||
|
List<Transform3D> transforms = kvp.Value;
|
||||||
|
|
||||||
|
multiMesh.InstanceCount = transforms.Count;
|
||||||
|
|
||||||
|
for (int i = 0; i < transforms.Count; i++)
|
||||||
|
{
|
||||||
|
multiMesh.SetInstanceTransform(i, transforms[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
public class Pathfinding
|
public class Pathfinding
|
||||||
{
|
{
|
||||||
private static AStar3D aStar = new AStar3D();
|
private static AStar3D aStar = new AStar3D();
|
||||||
private static Dictionary<Vector3I, long> coordToId = new();
|
private static Dictionary<Vector3I, long> coordToId = new Dictionary<Vector3I, long>();
|
||||||
private static Dictionary<long, Vector3I> idToCoord = new();
|
private static Dictionary<long, Vector3I> idToCoord = new Dictionary<long, Vector3I>();
|
||||||
private static long nextId = 1;
|
private static long nextId = 1;
|
||||||
private static Dictionary<int, (long fromId, long toId)> verticalConnections = new();
|
private static Dictionary<int, (long fromId, long toId)> verticalConnections = new Dictionary<int, (long fromId, long toId)>();
|
||||||
|
|
||||||
private static long GetOrCreateId(Vector3I coord)
|
private static long GetOrCreateId(Vector3I coord)
|
||||||
{
|
{
|
||||||
@@ -39,8 +38,7 @@ public class Pathfinding
|
|||||||
Vector3I coord = new Vector3I(x, y, z);
|
Vector3I coord = new Vector3I(x, y, z);
|
||||||
Tile tile = GameData.map[y].tiles[x, z];
|
Tile tile = GameData.map[y].tiles[x, z];
|
||||||
|
|
||||||
if (tile == null || tile.collapsedMesh == null)
|
if (tile == null || tile.collapsedMesh == null) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
long id = GetOrCreateId(coord);
|
long id = GetOrCreateId(coord);
|
||||||
|
|
||||||
@@ -49,24 +47,22 @@ public class Pathfinding
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var kvp in coordToId)
|
foreach (KeyValuePair<Vector3I, long> kvp in coordToId)
|
||||||
{
|
{
|
||||||
Vector3I from = kvp.Key;
|
Vector3I from = kvp.Key;
|
||||||
long fromId = kvp.Value;
|
long fromId = kvp.Value;
|
||||||
|
|
||||||
foreach (Vector3I offset in WFC.offsets3D)
|
foreach (Vector3I offset in WFC.offsets3D)
|
||||||
{
|
{
|
||||||
var to = new Vector3I(
|
Vector3I to = new Vector3I(
|
||||||
from.X + offset.X,
|
from.X + offset.X,
|
||||||
from.Y + offset.Y,
|
from.Y + offset.Y,
|
||||||
from.Z + offset.Z
|
from.Z + offset.Z
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!coordToId.ContainsKey(to))
|
if (!coordToId.ContainsKey(to)) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!WFC.CanWalk3D(from, to))
|
if (!WFC.CanWalk3D(from, to)) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
long toId = coordToId[to];
|
long toId = coordToId[to];
|
||||||
|
|
||||||
@@ -98,36 +94,38 @@ public class Pathfinding
|
|||||||
|
|
||||||
public static void UpdateGatePoint(int layer, bool isOpen)
|
public static void UpdateGatePoint(int layer, bool isOpen)
|
||||||
{
|
{
|
||||||
if (!verticalConnections.ContainsKey(layer))
|
if (!verticalConnections.ContainsKey(layer)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
var (fromId, toId) = verticalConnections[layer];
|
(long fromId, long toId) = verticalConnections[layer];
|
||||||
|
|
||||||
if (isOpen)
|
if (isOpen)
|
||||||
{
|
{
|
||||||
if (!aStar.ArePointsConnected(fromId, toId))
|
if (!aStar.ArePointsConnected(fromId, toId))
|
||||||
|
{
|
||||||
aStar.ConnectPoints(fromId, toId, true);
|
aStar.ConnectPoints(fromId, toId, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (aStar.ArePointsConnected(fromId, toId))
|
if (aStar.ArePointsConnected(fromId, toId))
|
||||||
|
{
|
||||||
aStar.DisconnectPoints(fromId, toId);
|
aStar.DisconnectPoints(fromId, toId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Vector3> GetPath(Vector3I start, Vector3I end)
|
public static List<Vector3> GetPath(Vector3I start, Vector3I end)
|
||||||
{
|
{
|
||||||
if (!coordToId.ContainsKey(start) || !coordToId.ContainsKey(end))
|
if (!coordToId.ContainsKey(start) || !coordToId.ContainsKey(end)) return new List<Vector3>();
|
||||||
return new List<Vector3>();
|
|
||||||
|
|
||||||
long startId = coordToId[start];
|
long startId = coordToId[start];
|
||||||
long endId = coordToId[end];
|
long endId = coordToId[end];
|
||||||
|
|
||||||
return aStar.GetPointPath(startId, endId).ToList();
|
return new List<Vector3>(aStar.GetPointPath(startId, endId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector3I GetClosestStartPoint(Vector3 robotPosition)
|
public static Vector3I GetClosestStartPoint(Vector3 robotPosition)
|
||||||
{
|
{
|
||||||
return idToCoord[aStar.GetClosestPoint(robotPosition)];
|
return idToCoord[aStar.GetClosestPoint(robotPosition)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,8 +5,9 @@ public class Placeholder
|
|||||||
public string name;
|
public string name;
|
||||||
public Transform3D transform;
|
public Transform3D transform;
|
||||||
|
|
||||||
public Placeholder(string name, Transform3D transform){
|
public Placeholder(string name, Transform3D transform)
|
||||||
|
{
|
||||||
this.name = name.Split("_")[0].ToLower();
|
this.name = name.Split("_")[0].ToLower();
|
||||||
this.transform = transform;
|
this.transform = transform;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
public class ResourceDistributor
|
||||||
|
{
|
||||||
|
public static Dictionary<string, Texture2D> resources = ResourceLoader.LoadResourceSymbols();
|
||||||
|
|
||||||
|
public static string GetResource(List<string> current)
|
||||||
|
{
|
||||||
|
List<string> availableResources = GetUnusedResources(current);
|
||||||
|
if (availableResources.Count <= 0)
|
||||||
|
{
|
||||||
|
availableResources = new List<string>(resources.Keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableResources[GameData.rand.Next(availableResources.Count)];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<string> GetUnusedResources(List<string> current)
|
||||||
|
{
|
||||||
|
List<string> result = new List<string>();
|
||||||
|
|
||||||
|
foreach (string resource in resources.Keys)
|
||||||
|
{
|
||||||
|
if (!current.Contains(resource))
|
||||||
|
{
|
||||||
|
result.Add(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,6 @@ public partial class Tile
|
|||||||
public bool wasVisited;
|
public bool wasVisited;
|
||||||
public event EventHandler OnTileVisited;
|
public event EventHandler OnTileVisited;
|
||||||
|
|
||||||
|
|
||||||
public void SetMeshes(Dictionary<string, MeshInstance3D> tileMeshes)
|
public void SetMeshes(Dictionary<string, MeshInstance3D> tileMeshes)
|
||||||
{
|
{
|
||||||
this.tileMeshes = new Dictionary<string, MeshInstance3D>(tileMeshes);
|
this.tileMeshes = new Dictionary<string, MeshInstance3D>(tileMeshes);
|
||||||
@@ -26,6 +25,7 @@ public partial class Tile
|
|||||||
{
|
{
|
||||||
if (collapsedMesh != null) return "";
|
if (collapsedMesh != null) return "";
|
||||||
if (tileMeshes.Keys.Count <= 0) return "ERR";
|
if (tileMeshes.Keys.Count <= 0) return "ERR";
|
||||||
|
|
||||||
collapsedMesh = (tile.Length > 0) ? tile : ChooseWeighted();
|
collapsedMesh = (tile.Length > 0) ? tile : ChooseWeighted();
|
||||||
tileMeshes.Clear();
|
tileMeshes.Clear();
|
||||||
return collapsedMesh;
|
return collapsedMesh;
|
||||||
@@ -74,6 +74,11 @@ public partial class Tile
|
|||||||
public void Reset(Dictionary<string, MeshInstance3D> tileMeshes)
|
public void Reset(Dictionary<string, MeshInstance3D> tileMeshes)
|
||||||
{
|
{
|
||||||
collapsedMesh = null;
|
collapsedMesh = null;
|
||||||
|
containsLight = false;
|
||||||
|
containsDecoration = false;
|
||||||
|
containsResource = false;
|
||||||
|
resource = null;
|
||||||
|
wasVisited = false;
|
||||||
SetMeshes(tileMeshes);
|
SetMeshes(tileMeshes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,16 +132,13 @@ public partial class Tile
|
|||||||
foreach (string key in contentMeshes.Keys)
|
foreach (string key in contentMeshes.Keys)
|
||||||
{
|
{
|
||||||
if (key.ToLower() != placeholder.name) continue;
|
if (key.ToLower() != placeholder.name) continue;
|
||||||
|
|
||||||
MeshInstance3D decoration = new MeshInstance3D
|
MeshInstance3D decoration = new MeshInstance3D
|
||||||
{
|
{
|
||||||
Mesh = contentMeshes[key].Mesh,
|
Mesh = contentMeshes[key].Mesh,
|
||||||
Position = placeholder.transform.Origin
|
Position = placeholder.transform.Origin
|
||||||
};
|
};
|
||||||
ContentNode.AddChild(decoration);
|
ContentNode.AddChild(decoration);
|
||||||
if (!key.ToLower().Contains("gate"))
|
|
||||||
{
|
|
||||||
//decoration.LookAt(transform.Origin, Vector3.Up);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,31 +47,31 @@ public class WFC
|
|||||||
|
|
||||||
public static Dictionary<string, HashSet<Direction>> tileConnections = new Dictionary<string, HashSet<Direction>>
|
public static Dictionary<string, HashSet<Direction>> tileConnections = new Dictionary<string, HashSet<Direction>>
|
||||||
{
|
{
|
||||||
["t_right"] = new() { Direction.Backward, Direction.Forward, Direction.Right, Direction.Up },
|
["t_right"] = new HashSet<Direction> { Direction.Backward, Direction.Forward, Direction.Right, Direction.Up },
|
||||||
["t_left"] = new() { Direction.Backward, Direction.Forward, Direction.Left, Direction.Up },
|
["t_left"] = new HashSet<Direction> { Direction.Backward, Direction.Forward, Direction.Left, Direction.Up },
|
||||||
["t_up"] = new() { Direction.Left, Direction.Right, Direction.Backward, Direction.Up },
|
["t_up"] = new HashSet<Direction> { Direction.Left, Direction.Right, Direction.Backward, Direction.Up },
|
||||||
["t_down"] = new() { Direction.Left, Direction.Right, Direction.Forward, Direction.Up },
|
["t_down"] = new HashSet<Direction> { Direction.Left, Direction.Right, Direction.Forward, Direction.Up },
|
||||||
|
|
||||||
["end_up"] = new() { Direction.Backward, Direction.Up },
|
["end_up"] = new HashSet<Direction> { Direction.Backward, Direction.Up },
|
||||||
["end_down"] = new() { Direction.Forward, Direction.Up },
|
["end_down"] = new HashSet<Direction> { Direction.Forward, Direction.Up },
|
||||||
["end_left"] = new() { Direction.Left, Direction.Up },
|
["end_left"] = new HashSet<Direction> { Direction.Left, Direction.Up },
|
||||||
["end_right"] = new() { Direction.Right, Direction.Up },
|
["end_right"] = new HashSet<Direction> { Direction.Right, Direction.Up },
|
||||||
|
|
||||||
["straight_left_right"] = new() { Direction.Left, Direction.Right, Direction.Up },
|
["straight_left_right"] = new HashSet<Direction> { Direction.Left, Direction.Right, Direction.Up },
|
||||||
["straight_up_down"] = new() { Direction.Backward, Direction.Forward, Direction.Up },
|
["straight_up_down"] = new HashSet<Direction> { Direction.Backward, Direction.Forward, Direction.Up },
|
||||||
|
|
||||||
["corner_up_left"] = new() { Direction.Backward, Direction.Left, Direction.Up },
|
["corner_up_left"] = new HashSet<Direction> { Direction.Backward, Direction.Left, Direction.Up },
|
||||||
["corner_up_right"] = new() { Direction.Backward, Direction.Right, Direction.Up },
|
["corner_up_right"] = new HashSet<Direction> { Direction.Backward, Direction.Right, Direction.Up },
|
||||||
["corner_down_left"] = new() { Direction.Forward, Direction.Left, Direction.Up },
|
["corner_down_left"] = new HashSet<Direction> { Direction.Forward, Direction.Left, Direction.Up },
|
||||||
["corner_down_right"] = new() { Direction.Forward, Direction.Right, Direction.Up },
|
["corner_down_right"] = new HashSet<Direction> { Direction.Forward, Direction.Right, Direction.Up },
|
||||||
|
|
||||||
["junction"] = new() { Direction.Backward, Direction.Forward, Direction.Left, Direction.Right, Direction.Up },
|
["junction"] = new HashSet<Direction> { Direction.Backward, Direction.Forward, Direction.Left, Direction.Right, Direction.Up },
|
||||||
["gate"] = new() { Direction.Backward, Direction.Forward, Direction.Left, Direction.Right, Direction.Up, Direction.Down },
|
["gate"] = new HashSet<Direction> { Direction.Backward, Direction.Forward, Direction.Left, Direction.Right, Direction.Up, Direction.Down },
|
||||||
|
|
||||||
["spawn"] = new() { Direction.Forward, Direction.Left },
|
["spawn"] = new HashSet<Direction> { Direction.Forward, Direction.Left },
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Dictionary<string, float> weights = new()
|
public static Dictionary<string, float> weights = new Dictionary<string, float>()
|
||||||
{
|
{
|
||||||
["junction"] = 3f,
|
["junction"] = 3f,
|
||||||
["t_up"] = 3f,
|
["t_up"] = 3f,
|
||||||
@@ -112,8 +112,8 @@ public class WFC
|
|||||||
|
|
||||||
public static bool CanConnect(string a, string b, Direction direction, bool checkWalking)
|
public static bool CanConnect(string a, string b, Direction direction, bool checkWalking)
|
||||||
{
|
{
|
||||||
var aDirs = tileConnections[a];
|
HashSet<Direction> aDirs = tileConnections[a];
|
||||||
var bDirs = tileConnections[b];
|
HashSet<Direction> bDirs = tileConnections[b];
|
||||||
|
|
||||||
bool aOpen = aDirs.Contains(direction);
|
bool aOpen = aDirs.Contains(direction);
|
||||||
bool bOpen = bDirs.Contains(Opposite(direction));
|
bool bOpen = bDirs.Contains(Opposite(direction));
|
||||||
@@ -126,15 +126,15 @@ public class WFC
|
|||||||
|
|
||||||
public static void FillAdjacencies()
|
public static void FillAdjacencies()
|
||||||
{
|
{
|
||||||
foreach (var tile in tileConnections.Keys)
|
foreach (string tile in tileConnections.Keys)
|
||||||
{
|
{
|
||||||
adjacency[tile] = new Dictionary<Direction, List<string>>();
|
adjacency[tile] = new Dictionary<Direction, List<string>>();
|
||||||
|
|
||||||
foreach (Direction dir in Enum.GetValues(typeof(Direction)))
|
foreach (Direction dir in Enum.GetValues(typeof(Direction)))
|
||||||
{
|
{
|
||||||
var valid = new List<string>();
|
List<string> valid = new List<string>();
|
||||||
|
|
||||||
foreach (var other in tileConnections.Keys)
|
foreach (string other in tileConnections.Keys)
|
||||||
{
|
{
|
||||||
if (CanConnect(tile, other, dir, false))
|
if (CanConnect(tile, other, dir, false))
|
||||||
valid.Add(other);
|
valid.Add(other);
|
||||||
@@ -147,14 +147,14 @@ public class WFC
|
|||||||
|
|
||||||
public static bool IsWalkable(Tile tile)
|
public static bool IsWalkable(Tile tile)
|
||||||
{
|
{
|
||||||
var dirs = tileConnections[tile.collapsedMesh];
|
HashSet<Direction> connections = tileConnections[tile.collapsedMesh];
|
||||||
return dirs.Count > 0 && !dirs.Contains(Direction.None);
|
return connections.Count > 0 && !connections.Contains(Direction.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool CanWalk(Tile[,] layer, Vector2I from, Vector2I to, Direction dir)
|
public static bool CanWalk(Tile[,] layer, Vector2I from, Vector2I to, Direction dir)
|
||||||
{
|
{
|
||||||
var fromTile = layer[from.X, from.Y];
|
Tile fromTile = layer[from.X, from.Y];
|
||||||
var toTile = layer[to.X, to.Y];
|
Tile toTile = layer[to.X, to.Y];
|
||||||
|
|
||||||
if (!IsWalkable(toTile))
|
if (!IsWalkable(toTile))
|
||||||
return false;
|
return false;
|
||||||
@@ -226,7 +226,7 @@ public class WFC
|
|||||||
if (!visited.Add(position)) continue;
|
if (!visited.Add(position)) continue;
|
||||||
for (int i = 0; i < offsets2D.Length; i++)
|
for (int i = 0; i < offsets2D.Length; i++)
|
||||||
{
|
{
|
||||||
var next = position + offsets2D[i];
|
Vector2I next = position + offsets2D[i];
|
||||||
|
|
||||||
if (!InBounds(next, layer.GetLength(0)))
|
if (!InBounds(next, layer.GetLength(0)))
|
||||||
continue;
|
continue;
|
||||||
@@ -263,18 +263,16 @@ public class WFC
|
|||||||
bool top = z == 0;
|
bool top = z == 0;
|
||||||
bool bottom = z == GameData.layerSize - 1;
|
bool bottom = z == GameData.layerSize - 1;
|
||||||
|
|
||||||
// Corners
|
if (left && top) return new List<string> { "corner_down_right" };
|
||||||
if (left && top) return new() { "corner_down_right" };
|
if (left && bottom) return new List<string> { "corner_up_right" };
|
||||||
if (left && bottom) return new() { "corner_up_right" };
|
if (right && top) return new List<string> { "corner_down_left" };
|
||||||
if (right && top) return new() { "corner_down_left" };
|
if (right && bottom) return new List<string> { "corner_up_left" };
|
||||||
if (right && bottom) return new() { "corner_up_left" };
|
|
||||||
|
|
||||||
// Edges
|
if (top) return new List<string> { "straight_left_right", "t_down" };
|
||||||
if (top) return new() { "straight_left_right", "t_down" };
|
if (bottom) return new List<string> { "straight_left_right", "t_up" };
|
||||||
if (bottom) return new() { "straight_left_right", "t_up" };
|
if (left) return new List<string> { "straight_up_down", "t_right" };
|
||||||
if (left) return new() { "straight_up_down", "t_right" };
|
if (right) return new List<string> { "straight_up_down", "t_left" };
|
||||||
if (right) return new() { "straight_up_down", "t_left" };
|
|
||||||
|
|
||||||
return new();
|
return new List<string>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using static GameData;
|
using static GameData;
|
||||||
|
|
||||||
public partial class World : Node3D
|
public partial class World : Node3D
|
||||||
@@ -9,11 +7,9 @@ public partial class World : Node3D
|
|||||||
public Dictionary<string, MeshInstance3D> tileMeshes;
|
public Dictionary<string, MeshInstance3D> tileMeshes;
|
||||||
public Dictionary<string, MeshInstance3D> contentMeshes;
|
public Dictionary<string, MeshInstance3D> contentMeshes;
|
||||||
public Dictionary<string, List<Placeholder>> tilePlaceholders;
|
public Dictionary<string, List<Placeholder>> tilePlaceholders;
|
||||||
PackedScene layerPrefab = ResourceLoader.LoadLayerPrefab();
|
private PackedScene layerPrefab = ResourceLoader.LoadLayerPrefab();
|
||||||
private Dictionary<string, MultiMeshInstance3D> multiMeshes = new();
|
private Dictionary<string, MultiMeshInstance3D> multiMeshes = new Dictionary<string, MultiMeshInstance3D>();
|
||||||
private Dictionary<string, Mesh> meshLibrary = new();
|
private Dictionary<string, Mesh> meshLibrary = new Dictionary<string, Mesh>();
|
||||||
Layer layerNode;
|
|
||||||
Pathfinding pathfinding;
|
|
||||||
|
|
||||||
private MultiMeshHandler multiMeshHandler;
|
private MultiMeshHandler multiMeshHandler;
|
||||||
|
|
||||||
@@ -26,9 +22,10 @@ public partial class World : Node3D
|
|||||||
|
|
||||||
tilePlaceholders = new Dictionary<string, List<Placeholder>>();
|
tilePlaceholders = new Dictionary<string, List<Placeholder>>();
|
||||||
|
|
||||||
foreach (var kvp in tileMeshes)
|
foreach (KeyValuePair<string, MeshInstance3D> kvp in tileMeshes)
|
||||||
{
|
{
|
||||||
tilePlaceholders[kvp.Key] = new List<Placeholder>();
|
tilePlaceholders[kvp.Key] = new List<Placeholder>();
|
||||||
|
|
||||||
foreach (Node3D child in kvp.Value.GetChildren())
|
foreach (Node3D child in kvp.Value.GetChildren())
|
||||||
{
|
{
|
||||||
tilePlaceholders[kvp.Key].Add(new Placeholder(child.Name, child.Transform));
|
tilePlaceholders[kvp.Key].Add(new Placeholder(child.Name, child.Transform));
|
||||||
@@ -56,19 +53,19 @@ public partial class World : Node3D
|
|||||||
|
|
||||||
private Dictionary<string, MultiMeshInstance3D> CreateMultiMeshes(Dictionary<string, Mesh> meshLibrary)
|
private Dictionary<string, MultiMeshInstance3D> CreateMultiMeshes(Dictionary<string, Mesh> meshLibrary)
|
||||||
{
|
{
|
||||||
var result = new Dictionary<string, MultiMeshInstance3D>();
|
Dictionary<string, MultiMeshInstance3D> result = new Dictionary<string, MultiMeshInstance3D>();
|
||||||
|
|
||||||
foreach (var kvp in meshLibrary)
|
foreach (KeyValuePair<string, Mesh> kvp in meshLibrary)
|
||||||
{
|
{
|
||||||
var mm = new MultiMesh
|
MultiMesh multiMesh = new MultiMesh
|
||||||
{
|
{
|
||||||
Mesh = kvp.Value,
|
Mesh = kvp.Value,
|
||||||
TransformFormat = MultiMesh.TransformFormatEnum.Transform3D
|
TransformFormat = MultiMesh.TransformFormatEnum.Transform3D
|
||||||
};
|
};
|
||||||
|
|
||||||
var instance = new MultiMeshInstance3D
|
MultiMeshInstance3D instance = new MultiMeshInstance3D
|
||||||
{
|
{
|
||||||
Multimesh = mm
|
Multimesh = multiMesh
|
||||||
};
|
};
|
||||||
|
|
||||||
AddChild(instance);
|
AddChild(instance);
|
||||||
@@ -79,17 +76,16 @@ public partial class World : Node3D
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
if (!canMove) return;
|
if (!canMove) return;
|
||||||
|
|
||||||
if (Input.IsActionJustPressed("layer_up") && currentLayer > 0) currentLayer--;
|
if (Input.IsActionJustPressed("layer_up") && currentLayer > 0) currentLayer--;
|
||||||
if (Input.IsActionJustPressed("layer_down") && currentLayer < ruinSize - 1 && map[currentLayer].isGateOpen) currentLayer++;
|
if (Input.IsActionJustPressed("layer_down") && currentLayer < ruinSize - 1 && map[currentLayer].isGateOpen) currentLayer++;
|
||||||
|
|
||||||
if (currentLayer != visibleLayer)
|
if (currentLayer != visibleLayer)
|
||||||
{
|
{
|
||||||
map[visibleLayer].ClearDecorations();
|
ShowLayer(currentLayer);
|
||||||
HandleRenderData(BuildRenderData(currentLayer));
|
|
||||||
visibleLayer = currentLayer;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,8 +93,9 @@ public partial class World : Node3D
|
|||||||
{
|
{
|
||||||
for (int layer = 0; layer < ruinSize; layer++)
|
for (int layer = 0; layer < ruinSize; layer++)
|
||||||
{
|
{
|
||||||
layerNode = layerPrefab.Instantiate<Layer>();
|
Layer layerNode = layerPrefab.Instantiate<Layer>();
|
||||||
AddChild(layerNode);
|
AddChild(layerNode);
|
||||||
|
|
||||||
if (layer == 0)
|
if (layer == 0)
|
||||||
{
|
{
|
||||||
layerNode.SetupLayer(layerSize, layer, tileMeshes, new Vector2I());
|
layerNode.SetupLayer(layerSize, layer, tileMeshes, new Vector2I());
|
||||||
@@ -113,6 +110,13 @@ public partial class World : Node3D
|
|||||||
SetupSpawn();
|
SetupSpawn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ShowLayer(int layer)
|
||||||
|
{
|
||||||
|
map[visibleLayer].ClearDecorations();
|
||||||
|
HandleRenderData(BuildRenderData(layer));
|
||||||
|
visibleLayer = layer;
|
||||||
|
}
|
||||||
|
|
||||||
private void SetupSpawn()
|
private void SetupSpawn()
|
||||||
{
|
{
|
||||||
map[0].tiles[0, 0].wasVisited = true;
|
map[0].tiles[0, 0].wasVisited = true;
|
||||||
@@ -122,14 +126,9 @@ public partial class World : Node3D
|
|||||||
map[0].tiles[0, 0].ContentNode.Visible = true;
|
map[0].tiles[0, 0].ContentNode.Visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleTileVisit(int level)
|
|
||||||
{
|
|
||||||
HandleRenderData(BuildRenderData(level));
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<TileRenderData> BuildRenderData(int layerIndex)
|
private List<TileRenderData> BuildRenderData(int layerIndex)
|
||||||
{
|
{
|
||||||
var result = new List<TileRenderData>();
|
List<TileRenderData> result = new List<TileRenderData>();
|
||||||
Layer layer = map[layerIndex];
|
Layer layer = map[layerIndex];
|
||||||
layer.ClearDecorations();
|
layer.ClearDecorations();
|
||||||
|
|
||||||
@@ -168,9 +167,9 @@ public partial class World : Node3D
|
|||||||
{
|
{
|
||||||
posX = rand.Next(layerSize);
|
posX = rand.Next(layerSize);
|
||||||
posY = rand.Next(layerSize);
|
posY = rand.Next(layerSize);
|
||||||
//Skip already placed lights and skip junction and gate as they do not contain lights
|
if (CannotContainLight(layer.tiles[posX, posY])) continue;
|
||||||
if (layer.tiles[posX, posY].collapsedMesh == "junction" || layer.tiles[posX, posY].collapsedMesh == "gate") continue;
|
|
||||||
if (layer.tiles[posX, posY].containsLight) continue;
|
if (layer.tiles[posX, posY].containsLight) continue;
|
||||||
|
|
||||||
layer.tiles[posX, posY].containsLight = true;
|
layer.tiles[posX, posY].containsLight = true;
|
||||||
currentLight++;
|
currentLight++;
|
||||||
}
|
}
|
||||||
@@ -180,6 +179,7 @@ public partial class World : Node3D
|
|||||||
posX = rand.Next(layerSize);
|
posX = rand.Next(layerSize);
|
||||||
posY = rand.Next(layerSize);
|
posY = rand.Next(layerSize);
|
||||||
if (layer.tiles[posX, posY].containsDecoration) continue;
|
if (layer.tiles[posX, posY].containsDecoration) continue;
|
||||||
|
|
||||||
layer.tiles[posX, posY].containsDecoration = true;
|
layer.tiles[posX, posY].containsDecoration = true;
|
||||||
currentDecoration++;
|
currentDecoration++;
|
||||||
}
|
}
|
||||||
@@ -189,6 +189,7 @@ public partial class World : Node3D
|
|||||||
posX = rand.Next(layerSize);
|
posX = rand.Next(layerSize);
|
||||||
posY = rand.Next(layerSize);
|
posY = rand.Next(layerSize);
|
||||||
if (layer.tiles[posX, posY].containsResource) continue;
|
if (layer.tiles[posX, posY].containsResource) continue;
|
||||||
|
|
||||||
layer.tiles[posX, posY].containsResource = true;
|
layer.tiles[posX, posY].containsResource = true;
|
||||||
layer.tiles[posX, posY].resource = new GameResource(ResourceDistributor.GetResource(layer.currentResources));
|
layer.tiles[posX, posY].resource = new GameResource(ResourceDistributor.GetResource(layer.currentResources));
|
||||||
layer.currentResources.Add(layer.tiles[posX, posY].resource.name);
|
layer.currentResources.Add(layer.tiles[posX, posY].resource.name);
|
||||||
@@ -196,6 +197,11 @@ public partial class World : Node3D
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool CannotContainLight(Tile tile)
|
||||||
|
{
|
||||||
|
return tile.collapsedMesh == "junction" || tile.collapsedMesh == "gate";
|
||||||
|
}
|
||||||
|
|
||||||
private void HandleRenderData(List<TileRenderData> renderData)
|
private void HandleRenderData(List<TileRenderData> renderData)
|
||||||
{
|
{
|
||||||
multiMeshHandler.Build(renderData);
|
multiMeshHandler.Build(renderData);
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Godot;
|
|
||||||
|
|
||||||
public class ResourceDistributor
|
|
||||||
{
|
|
||||||
public static Dictionary<string, Texture2D> resources = ResourceLoader.LoadResourceSymbols();
|
|
||||||
|
|
||||||
public static string GetResource(List<string> current)
|
|
||||||
{
|
|
||||||
List<string> diff = resources.Keys.Except(current).ToList();
|
|
||||||
if (diff.Count <= 0)
|
|
||||||
{
|
|
||||||
return resources.Keys.ToList()[GameData.rand.Next(resources.Keys.Count)];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return diff[GameData.rand.Next(diff.Count)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user