Finished first EA Version #1
@@ -474,9 +474,9 @@ public partial class TestRunner : Node
|
||||
amount = 2
|
||||
};
|
||||
|
||||
AssertEqual(NodeResult.SUCCESS, node.Execute(null, 0), "first iteration");
|
||||
AssertEqual(NodeResult.SUCCESS, node.Execute(null, 0), "second iteration");
|
||||
AssertEqual(NodeResult.CONDITIONFALSE, node.Execute(null, 0), "loop finished");
|
||||
AssertEqual(NodeResult.CONDITIONFALSE, node.Execute(null, 0), "first iteration");
|
||||
AssertEqual(NodeResult.CONDITIONFALSE, node.Execute(null, 0), "second iteration");
|
||||
AssertEqual(NodeResult.SUCCESS, node.Execute(null, 0), "loop finished");
|
||||
}
|
||||
|
||||
private void TestStartNodeSucceedsImmediately()
|
||||
|
||||
@@ -154,4 +154,9 @@ public static class UIStyle
|
||||
{
|
||||
return Warning;
|
||||
}
|
||||
|
||||
public static Color GetBorderColor()
|
||||
{
|
||||
return Accent;
|
||||
}
|
||||
}
|
||||
|
||||
+211
-25
@@ -4,38 +4,43 @@ using System.Collections.Generic;
|
||||
|
||||
public partial class Map : PanelContainer
|
||||
{
|
||||
private const int TileTextureSize = 32;
|
||||
private const int RobotBorderWidth = 2;
|
||||
private const double RobotMapUpdateInterval = 0.2;
|
||||
|
||||
[Export] GridContainer grid;
|
||||
private HashSet<Tile> handledTiles = new HashSet<Tile>();
|
||||
private Dictionary<Tile, TextureRect> textureMap = new Dictionary<Tile, TextureRect>();
|
||||
private Dictionary<Vector2I, List<Robot>> visibleRobots = new Dictionary<Vector2I, List<Robot>>();
|
||||
private double robotMapUpdateTimer = 0.0;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
grid.Columns = GameData.layerSize + 1;
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (!Visible) return;
|
||||
|
||||
robotMapUpdateTimer += delta;
|
||||
if (robotMapUpdateTimer < RobotMapUpdateInterval) return;
|
||||
|
||||
robotMapUpdateTimer = 0.0;
|
||||
UpdateVisibleRobotTiles();
|
||||
}
|
||||
|
||||
public void ShowMap()
|
||||
{
|
||||
if (!Visible) return;
|
||||
|
||||
ClearGrid();
|
||||
robotMapUpdateTimer = 0.0;
|
||||
|
||||
Tile[,] tiles = GameData.map[GameData.currentLayer].tiles;
|
||||
int size = GameData.layerSize;
|
||||
|
||||
Dictionary<Vector2I, List<Robot>> visibleRobots = new Dictionary<Vector2I, List<Robot>>();
|
||||
|
||||
Vector3I tilePos;
|
||||
Vector2I key;
|
||||
|
||||
foreach(Robot robot in GameData.robots)
|
||||
{
|
||||
if(!robot.showOnMap) continue;
|
||||
tilePos = Pathfinding.GetClosestStartPoint(robot.Position);
|
||||
if(tilePos.Y != GameData.visibleLayer) continue;
|
||||
key = new Vector2I(tilePos.X, tilePos.Z);
|
||||
if(!visibleRobots.ContainsKey(key)) visibleRobots.Add(key, new List<Robot>());
|
||||
visibleRobots[key].Add(robot);
|
||||
}
|
||||
visibleRobots = BuildVisibleRobots();
|
||||
|
||||
for (int z = -1; z < size; z++)
|
||||
{
|
||||
@@ -47,7 +52,8 @@ public partial class Map : PanelContainer
|
||||
continue;
|
||||
}
|
||||
|
||||
TextureRect texture = CreateTileTexture(tiles[x, z]);
|
||||
Vector2I tilePosition = new Vector2I(x, z);
|
||||
TextureRect texture = CreateTileTexture(tiles[x, z], GetRobotsOnTile(visibleRobots, tilePosition));
|
||||
textureMap[tiles[x, z]] = texture;
|
||||
|
||||
if (!handledTiles.Contains(tiles[x, z]))
|
||||
@@ -65,6 +71,116 @@ public partial class Map : PanelContainer
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateVisibleRobotTiles()
|
||||
{
|
||||
Dictionary<Vector2I, List<Robot>> updatedVisibleRobots = BuildVisibleRobots();
|
||||
if (HasSameVisibleRobots(visibleRobots, updatedVisibleRobots)) return;
|
||||
|
||||
List<Vector2I> affectedTiles = GetAffectedRobotTiles(visibleRobots, updatedVisibleRobots);
|
||||
visibleRobots = updatedVisibleRobots;
|
||||
|
||||
foreach (Vector2I tilePosition in affectedTiles)
|
||||
{
|
||||
UpdateTileAtPosition(tilePosition);
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasSameVisibleRobots(
|
||||
Dictionary<Vector2I, List<Robot>> oldRobots,
|
||||
Dictionary<Vector2I, List<Robot>> newRobots
|
||||
)
|
||||
{
|
||||
if (oldRobots.Count != newRobots.Count) return false;
|
||||
|
||||
foreach (KeyValuePair<Vector2I, List<Robot>> kvp in oldRobots)
|
||||
{
|
||||
if (!newRobots.ContainsKey(kvp.Key)) return false;
|
||||
if (!ContainsSameRobots(kvp.Value, newRobots[kvp.Key])) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ContainsSameRobots(List<Robot> oldRobots, List<Robot> newRobots)
|
||||
{
|
||||
if (oldRobots.Count != newRobots.Count) return false;
|
||||
|
||||
foreach (Robot robot in oldRobots)
|
||||
{
|
||||
if (!newRobots.Contains(robot)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<Vector2I> GetAffectedRobotTiles(
|
||||
Dictionary<Vector2I, List<Robot>> oldRobots,
|
||||
Dictionary<Vector2I, List<Robot>> newRobots
|
||||
)
|
||||
{
|
||||
List<Vector2I> affectedTiles = new List<Vector2I>();
|
||||
|
||||
foreach (Vector2I tilePosition in oldRobots.Keys)
|
||||
{
|
||||
AddAffectedTile(affectedTiles, tilePosition);
|
||||
}
|
||||
|
||||
foreach (Vector2I tilePosition in newRobots.Keys)
|
||||
{
|
||||
AddAffectedTile(affectedTiles, tilePosition);
|
||||
}
|
||||
|
||||
return affectedTiles;
|
||||
}
|
||||
|
||||
private void AddAffectedTile(List<Vector2I> affectedTiles, Vector2I tilePosition)
|
||||
{
|
||||
if (affectedTiles.Contains(tilePosition)) return;
|
||||
|
||||
affectedTiles.Add(tilePosition);
|
||||
}
|
||||
|
||||
private void UpdateTileAtPosition(Vector2I tilePosition)
|
||||
{
|
||||
if (tilePosition.X < 0 || tilePosition.X >= GameData.layerSize) return;
|
||||
if (tilePosition.Y < 0 || tilePosition.Y >= GameData.layerSize) return;
|
||||
|
||||
Tile tile = GameData.map[GameData.currentLayer].tiles[tilePosition.X, tilePosition.Y];
|
||||
if (!textureMap.ContainsKey(tile)) return;
|
||||
|
||||
UpdateMap(tile, textureMap[tile]);
|
||||
}
|
||||
|
||||
private Dictionary<Vector2I, List<Robot>> BuildVisibleRobots()
|
||||
{
|
||||
Dictionary<Vector2I, List<Robot>> visibleRobots = new Dictionary<Vector2I, List<Robot>>();
|
||||
|
||||
foreach (Robot robot in GameData.robots)
|
||||
{
|
||||
if (!robot.showOnMap) continue;
|
||||
|
||||
Vector3I tilePos = Pathfinding.GetClosestStartPoint(robot.Position);
|
||||
if (tilePos.Y != GameData.currentLayer) continue;
|
||||
|
||||
Vector2I key = new Vector2I(tilePos.X, tilePos.Z);
|
||||
if (!visibleRobots.ContainsKey(key))
|
||||
{
|
||||
visibleRobots.Add(key, new List<Robot>());
|
||||
}
|
||||
|
||||
visibleRobots[key].Add(robot);
|
||||
}
|
||||
|
||||
return visibleRobots;
|
||||
}
|
||||
|
||||
private List<Robot> GetRobotsOnTile(Dictionary<Vector2I, List<Robot>> visibleRobots, Vector2I tilePosition)
|
||||
{
|
||||
if (!visibleRobots.ContainsKey(tilePosition)) return new List<Robot>();
|
||||
|
||||
return visibleRobots[tilePosition];
|
||||
}
|
||||
|
||||
private void ClearGrid()
|
||||
{
|
||||
foreach (Node node in grid.GetChildren())
|
||||
@@ -91,7 +207,7 @@ public partial class Map : PanelContainer
|
||||
return label;
|
||||
}
|
||||
|
||||
private TextureRect CreateTileTexture(Tile tile)
|
||||
private TextureRect CreateTileTexture(Tile tile, List<Robot> robotsOnTile)
|
||||
{
|
||||
TextureRect texture = new TextureRect
|
||||
{
|
||||
@@ -100,7 +216,7 @@ public partial class Map : PanelContainer
|
||||
StretchMode = TextureRect.StretchModeEnum.Scale
|
||||
};
|
||||
|
||||
UpdateTileTexture(tile, texture);
|
||||
UpdateTileTexture(tile, texture, robotsOnTile);
|
||||
return texture;
|
||||
}
|
||||
|
||||
@@ -121,26 +237,41 @@ public partial class Map : PanelContainer
|
||||
{
|
||||
if (!IsInstanceValid(texture)) return;
|
||||
|
||||
UpdateTileTexture(tile, texture);
|
||||
UpdateTileTexture(tile, texture, GetRobotsOnTile(
|
||||
BuildVisibleRobots(),
|
||||
tile.GridPosition
|
||||
));
|
||||
}
|
||||
|
||||
private void UpdateTileTexture(Tile tile, TextureRect texture)
|
||||
private void UpdateTileTexture(Tile tile, TextureRect texture, List<Robot> robotsOnTile)
|
||||
{
|
||||
Texture2D tileTexture;
|
||||
string tooltipText;
|
||||
|
||||
if (!tile.wasVisited && !GameData.debugMode)
|
||||
{
|
||||
texture.Texture = GenerateTexture(32, new Color(0, 0, 0, 1));
|
||||
texture.TooltipText = "Not explored";
|
||||
tileTexture = GenerateTexture(TileTextureSize, new Color(0, 0, 0, 1));
|
||||
tooltipText = "Not explored";
|
||||
}
|
||||
else if (tile.containsResource)
|
||||
{
|
||||
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})";
|
||||
tileTexture = ResourceDistributor.resources[tile.resource.name];
|
||||
tooltipText = tile.resource.item.GetReadableName() + GetPositionTooltip(tile);
|
||||
}
|
||||
else
|
||||
{
|
||||
texture.Texture = GenerateTexture(32, new Color(0, 0, 0, 0));
|
||||
texture.TooltipText = "";
|
||||
tileTexture = GenerateTexture(TileTextureSize, new Color(0, 0, 0, 0));
|
||||
tooltipText = "";
|
||||
}
|
||||
|
||||
if (robotsOnTile.Count > 0)
|
||||
{
|
||||
tileTexture = AddBorder(tileTexture, UIStyle.GetBorderColor(), RobotBorderWidth);
|
||||
tooltipText += GetRobotTooltip(robotsOnTile, tooltipText.Length > 0);
|
||||
}
|
||||
|
||||
texture.Texture = tileTexture;
|
||||
texture.TooltipText = tooltipText;
|
||||
}
|
||||
|
||||
public Texture2D GenerateTexture(int size, Color fillColor)
|
||||
@@ -150,4 +281,59 @@ public partial class Map : PanelContainer
|
||||
|
||||
return ImageTexture.CreateFromImage(image);
|
||||
}
|
||||
|
||||
public Texture2D AddBorder(Texture2D texture, Color borderColor, int borderWidth)
|
||||
{
|
||||
if (texture == null) return null;
|
||||
if (borderWidth <= 0) return texture;
|
||||
|
||||
Image sourceImage = texture.GetImage();
|
||||
if (sourceImage == null) return texture;
|
||||
|
||||
if (sourceImage.GetFormat() != Image.Format.Rgba8)
|
||||
{
|
||||
sourceImage.Convert(Image.Format.Rgba8);
|
||||
}
|
||||
|
||||
int width = sourceImage.GetWidth();
|
||||
int height = sourceImage.GetHeight();
|
||||
int actualBorderWidth = Math.Min(borderWidth, Math.Min(width, height) / 2);
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
for (int y = 0; y < actualBorderWidth; y++)
|
||||
{
|
||||
sourceImage.SetPixel(x, y, borderColor);
|
||||
sourceImage.SetPixel(x, height - 1 - y, borderColor);
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = actualBorderWidth; y < height - actualBorderWidth; y++)
|
||||
{
|
||||
for (int x = 0; x < actualBorderWidth; x++)
|
||||
{
|
||||
sourceImage.SetPixel(x, y, borderColor);
|
||||
sourceImage.SetPixel(width - 1 - x, y, borderColor);
|
||||
}
|
||||
}
|
||||
|
||||
return ImageTexture.CreateFromImage(sourceImage);
|
||||
}
|
||||
|
||||
private string GetPositionTooltip(Tile tile)
|
||||
{
|
||||
return $"\r(X: {tile.GridPosition.X},Y: {GameData.currentLayer},Z: {tile.GridPosition.Y})";
|
||||
}
|
||||
|
||||
private string GetRobotTooltip(List<Robot> robotsOnTile, bool addSeparator)
|
||||
{
|
||||
string tooltip = addSeparator ? "\rRobots:" : "Robots:";
|
||||
|
||||
foreach (Robot robot in robotsOnTile)
|
||||
{
|
||||
tooltip += "\r- " + robot.Name;
|
||||
}
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user