142 lines
5.0 KiB
C#
142 lines
5.0 KiB
C#
using Godot;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
//using Dictionary = Godot.Collections.Dictionary;
|
|
|
|
public class StreamContainer : Spatial
|
|
{
|
|
// scene nodes
|
|
private MeshInstance _bounds;
|
|
private Spatial _activeTiles;
|
|
|
|
// resources
|
|
private PackedScene _hexTileScene = GD.Load<PackedScene>("res://scenes/HexTile3D.tscn");
|
|
|
|
// exports
|
|
[Export] public Vector2 Dimensions = new Vector2(8, 4);
|
|
|
|
// other members
|
|
private Rect2 _worldRect;
|
|
private Rect2 _currentOffsetCoordRect;
|
|
private Rect2 _oldOffsetCoordRect;
|
|
private HexGrid _hexGrid;
|
|
|
|
private Dictionary<Vector2, Spatial> _coordToTile = new Dictionary<Vector2, Spatial>();
|
|
public List<Vector2> RemovedCoords = new List<Vector2>();
|
|
public List<Vector2> AddedCoords = new List<Vector2>();
|
|
|
|
public Rect2 CurrentOffsetCoordRect
|
|
{
|
|
get { return _currentOffsetCoordRect; }
|
|
}
|
|
|
|
// Called when the node enters the scene tree for the first time.
|
|
public override void _Ready()
|
|
{
|
|
_bounds = GetNode<MeshInstance>("Bounds");
|
|
_activeTiles = GetNode<Spatial>("ActiveTiles");
|
|
|
|
_hexGrid = new HexGrid();
|
|
|
|
Transform boundsTransform = Transform.Identity;
|
|
boundsTransform = boundsTransform.Scaled(new Vector3(Dimensions.x, 1, Dimensions.y));
|
|
_bounds.Transform = boundsTransform;
|
|
|
|
Spatial hexTile3d = (Spatial)_hexTileScene.Instance();
|
|
AddChild(hexTile3d);
|
|
}
|
|
|
|
|
|
public void UpdateRects(Vector2 centerPlane)
|
|
{
|
|
_oldOffsetCoordRect = _currentOffsetCoordRect;
|
|
|
|
Vector2 bottomLeftCoord = centerPlane - new Vector2(Dimensions.x / 2, Dimensions.y / 2);
|
|
Vector2 topRightCoord = centerPlane + new Vector2(Dimensions.x / 2, Dimensions.y / 2);
|
|
|
|
_worldRect = new Rect2(bottomLeftCoord, Dimensions);
|
|
// GD.Print("World rect now: " + _worldRect.ToString() + " center: " + _worldRect.GetCenter());
|
|
|
|
// y axis needs to be inverted as HexGrid's offset coordinates use the opposite axis direction
|
|
HexCell bottomLeftCell = _hexGrid.GetHexAt(new Vector2(bottomLeftCoord.x, topRightCoord.y));
|
|
HexCell topRightCell = _hexGrid.GetHexAt(new Vector2(topRightCoord.x, bottomLeftCoord.y));
|
|
_currentOffsetCoordRect = new Rect2(bottomLeftCell.OffsetCoords,
|
|
topRightCell.OffsetCoords - bottomLeftCell.OffsetCoords + Vector2.One);
|
|
// GD.Print("Offset rect now: " + _currentOffsetCoordRect.ToString() + " center: " +
|
|
// _currentOffsetCoordRect.GetCenter());
|
|
|
|
Transform boundsTransform = _bounds.Transform;
|
|
boundsTransform.origin.x = centerPlane.x;
|
|
boundsTransform.origin.z = centerPlane.y;
|
|
_bounds.Transform = boundsTransform;
|
|
|
|
// GD.Print("Bounds Transform: " + boundsTransform.ToString());
|
|
// GD.Print("Bounds Global : " + _bounds.GlobalTransform.ToString());
|
|
|
|
if (!_currentOffsetCoordRect.Equals(_oldOffsetCoordRect))
|
|
{
|
|
UpdateTileCache();
|
|
}
|
|
}
|
|
|
|
|
|
public void UpdateTileCache()
|
|
{
|
|
RemovedCoords.Clear();
|
|
AddedCoords.Clear();
|
|
|
|
Rect2 expandedRect = _currentOffsetCoordRect.Merge(_oldOffsetCoordRect);
|
|
|
|
foreach (int coord_x in Enumerable.Range(Mathf.FloorToInt(expandedRect.Position.x), Mathf.CeilToInt(expandedRect.Size.x)))
|
|
{
|
|
foreach (int coord_y in Enumerable.Range(Mathf.FloorToInt(expandedRect.Position.y),
|
|
Mathf.CeilToInt(expandedRect.Size.y)))
|
|
{
|
|
Vector2 coord = new Vector2(coord_x, coord_y);
|
|
bool isInCurrent = _currentOffsetCoordRect.HasPoint(coord);
|
|
bool isInOld = _oldOffsetCoordRect.HasPoint(coord);
|
|
|
|
if (isInCurrent && !isInOld)
|
|
{
|
|
AddedCoords.Add(coord);
|
|
GetTile3dAt(coord);
|
|
}
|
|
else if (isInOld && !isInCurrent)
|
|
{
|
|
RemovedCoords.Add(coord);
|
|
if (_coordToTile.Keys.Contains(coord))
|
|
{
|
|
Spatial tile3d = _coordToTile[coord];
|
|
_activeTiles.RemoveChild(tile3d);
|
|
tile3d.QueueFree();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public Spatial GetTile3dAt(Vector2 offsetCoords)
|
|
{
|
|
if (!_coordToTile.Keys.Contains(offsetCoords))
|
|
{
|
|
Spatial tile3d = (Spatial)_hexTileScene.Instance();
|
|
HexCell cell = new HexCell();
|
|
cell.OffsetCoords = offsetCoords;
|
|
Vector2 cellPlaneCoords = _hexGrid.GetHexCenter(cell);
|
|
Transform tile3dTransform = Transform.Identity;
|
|
tile3dTransform.origin = new Vector3(cellPlaneCoords.x, GD.Randf() * 0.1f, cellPlaneCoords.y);
|
|
tile3d.Transform = tile3dTransform;
|
|
_activeTiles.AddChild(tile3d);
|
|
_coordToTile[offsetCoords] = tile3d;
|
|
}
|
|
|
|
return _coordToTile[offsetCoords];
|
|
}
|
|
|
|
public void SetCenterTile(HexCell cell)
|
|
{
|
|
UpdateRects(_hexGrid.GetHexCenter(cell));
|
|
}
|
|
} |