Finished first EA Version #1
@@ -19,7 +19,7 @@ public partial class GameData
|
||||
public static float tileWidth = 6;
|
||||
public static float tileHeight = 4;
|
||||
public static SortedDictionary<string, ItemData> availableItems = ResourceLoader.LoadItems();
|
||||
public static Dictionary<string, ResearchData> availableResearch = ResourceLoader.LoadResearch();
|
||||
public static Dictionary<string, Research> availableResearch = ResourceLoader.LoadResearch();
|
||||
|
||||
//--- PLAYER ADJUSTABLE VALUES ---
|
||||
//Color used in primary objects (e.g. Robots)
|
||||
|
||||
@@ -102,18 +102,18 @@ public partial class ResourceLoader
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Dictionary<string, ResearchData> LoadResearch()
|
||||
public static Dictionary<string, Research> LoadResearch()
|
||||
{
|
||||
|
||||
FileAccess file = FileAccess.Open("res://Assets/Research.json", FileAccess.ModeFlags.Read);
|
||||
string json = file.GetAsText();
|
||||
|
||||
Dictionary<string, ResearchData> result = new();
|
||||
Dictionary<string, Research> result = new();
|
||||
|
||||
List<ResearchData> researches = JsonSerializer.Deserialize<List<ResearchData>>(json);
|
||||
foreach (ResearchData research in researches)
|
||||
{
|
||||
result.Add(research.Id, research);
|
||||
result.Add(research.Id, new Research(research));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -3,9 +3,15 @@ using Godot;
|
||||
public class Research
|
||||
{
|
||||
public ResearchData data;
|
||||
public bool isResearched = false;
|
||||
public double elapsedResearchTime = 0;
|
||||
public bool paidResources = false;
|
||||
public ResearchState state;
|
||||
|
||||
public Research(ResearchData data)
|
||||
{
|
||||
this.data = data;
|
||||
state = ResearchState.UNDEFINED;
|
||||
}
|
||||
|
||||
public ResearchResult Execute(double delta)
|
||||
{
|
||||
@@ -20,7 +26,7 @@ public class Research
|
||||
elapsedResearchTime += delta;
|
||||
if (elapsedResearchTime >= data.CraftTime)
|
||||
{
|
||||
isResearched = true;
|
||||
state = ResearchState.RESEARCHED;
|
||||
return ResearchResult.FINISHED;
|
||||
}
|
||||
return ResearchResult.RESEARCHING;
|
||||
|
||||
@@ -1,49 +1,118 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
public partial class ResearchList : PanelContainer
|
||||
{
|
||||
[Export] GraphEdit researchGraph;
|
||||
[Export] private GraphEdit researchGraph;
|
||||
|
||||
private const float StartXDivisor = 32f;
|
||||
private const float StartYDivisor = 4f;
|
||||
private const float NodeSpacingMultiplier = 10f;
|
||||
|
||||
private List<string> reloadKeys = new List<string>();
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
foreach (ResearchData research in GameData.availableResearch.Values)
|
||||
RecalculateResearchStates();
|
||||
SetupGraph();
|
||||
}
|
||||
|
||||
public void SetupGraph()
|
||||
{
|
||||
reloadKeys = new List<string>();
|
||||
ClearGraph();
|
||||
CreateResearchNodes();
|
||||
CreateResearchConnections();
|
||||
}
|
||||
|
||||
private void ClearGraph()
|
||||
{
|
||||
foreach (Dictionary connection in researchGraph.GetConnectionList())
|
||||
{
|
||||
researchGraph.AddChild(CreateItemNode(research.Id, research.Texture));
|
||||
researchGraph.DisconnectNode(
|
||||
connection["from_node"].AsStringName(),
|
||||
(int)connection["from_port"],
|
||||
connection["to_node"].AsStringName(),
|
||||
(int)connection["to_port"]
|
||||
);
|
||||
}
|
||||
foreach (ResearchData research in GameData.availableResearch.Values)
|
||||
|
||||
foreach (Node child in researchGraph.GetChildren())
|
||||
{
|
||||
if (child is GraphNode)
|
||||
{
|
||||
researchGraph.RemoveChild(child);
|
||||
child.QueueFree();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateResearchNodes()
|
||||
{
|
||||
foreach (Research research in GameData.availableResearch.Values)
|
||||
{
|
||||
GD.Print(research.state);
|
||||
GraphNode node = CreateResearchNode(
|
||||
research.data.Id,
|
||||
research.data.Texture,
|
||||
research.state
|
||||
);
|
||||
|
||||
researchGraph.AddChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateResearchConnections()
|
||||
{
|
||||
foreach (Research research in GameData.availableResearch.Values)
|
||||
{
|
||||
string prerequisite = research.data.Research;
|
||||
string current = research.data.Id;
|
||||
|
||||
if (string.IsNullOrEmpty(prerequisite))
|
||||
continue;
|
||||
|
||||
if (!researchGraph.HasNode(prerequisite) || !researchGraph.HasNode(current))
|
||||
continue;
|
||||
|
||||
researchGraph.ConnectNode(
|
||||
research.Research,
|
||||
0,
|
||||
research.Id,
|
||||
0
|
||||
);
|
||||
prerequisite,
|
||||
0,
|
||||
current,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
private GraphNode CreateResearchNode(string id, string texturePath, ResearchState state)
|
||||
{
|
||||
Texture2D texture = GD.Load<Texture2D>(texturePath);
|
||||
Color stateColor = GetColorByState(state);
|
||||
|
||||
}
|
||||
|
||||
private GraphNode CreateItemNode(string id, string texturePath)
|
||||
{
|
||||
Vector2 viewportSize = GetViewport().GetVisibleRect().Size;
|
||||
TextureRect icon = new TextureRect
|
||||
{
|
||||
Texture = GD.Load<Texture2D>(texturePath),
|
||||
StretchMode = TextureRect.StretchModeEnum.KeepAspectCentered
|
||||
Texture = texture,
|
||||
StretchMode = TextureRect.StretchModeEnum.KeepAspectCentered,
|
||||
CustomMinimumSize = new Vector2(64, 64),
|
||||
SelfModulate = stateColor
|
||||
};
|
||||
//Step 1: Place the node in the visible field for the player
|
||||
Vector2 nodePosition = new Vector2(viewportSize.X / 32, viewportSize.Y / 4);
|
||||
//Step 2: Modify position by nodeIndex
|
||||
nodePosition = nodePosition + new Vector2(GameData.availableResearch.Count * -icon.Texture.GetWidth() + researchGraph.GetChildCount() * icon.Texture.GetWidth() * 10, 0);
|
||||
|
||||
Button button = new Button
|
||||
{
|
||||
Text = "Research",
|
||||
Disabled = state != ResearchState.AVAILABLE
|
||||
};
|
||||
|
||||
button.Pressed += () => OnResearchPressed(id);
|
||||
|
||||
GraphNode node = new GraphNode
|
||||
{
|
||||
Name = id,
|
||||
Title = id,
|
||||
PositionOffset = nodePosition
|
||||
PositionOffset = GetNodePosition(texture),
|
||||
SelfModulate = stateColor
|
||||
};
|
||||
|
||||
node.SetSlot(
|
||||
@@ -57,7 +126,86 @@ public partial class ResearchList : PanelContainer
|
||||
);
|
||||
|
||||
node.AddChild(icon);
|
||||
node.AddChild(button);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private Vector2 GetNodePosition(Texture2D texture)
|
||||
{
|
||||
Vector2 viewportSize = GetViewport().GetVisibleRect().Size;
|
||||
|
||||
float textureWidth = texture?.GetWidth() ?? 64f;
|
||||
|
||||
Vector2 startPosition = new Vector2(
|
||||
viewportSize.X / StartXDivisor,
|
||||
viewportSize.Y / StartYDivisor
|
||||
);
|
||||
|
||||
float xOffset =
|
||||
GameData.availableResearch.Count * -textureWidth +
|
||||
researchGraph.GetChildCount() * textureWidth * NodeSpacingMultiplier;
|
||||
|
||||
return startPosition + new Vector2(xOffset, 0);
|
||||
}
|
||||
|
||||
private void OnResearchPressed(string id)
|
||||
{
|
||||
GameData.availableResearch[id].state = ResearchState.RESEARCHED;
|
||||
RecalculateResearchStates();
|
||||
SetupGraph();
|
||||
}
|
||||
|
||||
private void RecalculateResearchStates()
|
||||
{
|
||||
bool changedState;
|
||||
foreach (string key in GameData.availableResearch.Keys)
|
||||
{
|
||||
changedState = false;
|
||||
if (reloadKeys.Contains(key)) continue;
|
||||
reloadKeys.Add(key);
|
||||
|
||||
//Already researched
|
||||
if (GameData.availableResearch[key].state == ResearchState.RESEARCHED)
|
||||
{
|
||||
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 Color GetColorByState(ResearchState state)
|
||||
{
|
||||
return state switch
|
||||
{
|
||||
ResearchState.AVAILABLE => Colors.White,
|
||||
ResearchState.LOCKED => new Color(0.6f, 0.6f, 0.6f, 0.5f),
|
||||
ResearchState.RESEARCHED => new Color(0.7f, 1f, 0.7f, 1f),
|
||||
_ => Colors.Red
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
public enum ResearchState
|
||||
{
|
||||
UNDEFINED,
|
||||
RESEARCHED,
|
||||
AVAILABLE,
|
||||
LOCKED
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://b57yhucbav37c
|
||||
Reference in New Issue
Block a user