using System; 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("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 Random _tileTypeRandom; private Dictionary _coordToTile = new Dictionary(); public List RemovedCoords = new List(); public List AddedCoords = new List(); public Rect2 CurrentOffsetCoordRect { get { return _currentOffsetCoordRect; } } // Called when the node enters the scene tree for the first time. public override void _Ready() { _bounds = GetNode("Bounds"); _activeTiles = GetNode("ActiveTiles"); _tileTypeRandom = new Random(); _hexGrid = new HexGrid(); Transform boundsTransform = Transform.Identity; boundsTransform = boundsTransform.Scaled(new Vector3(Dimensions.x, 1, Dimensions.y)); _bounds.Transform = boundsTransform; } 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(); _coordToTile.Remove(coord); } } } } } public Spatial GetTile3dAt(Vector2 offsetCoords) { if (!_coordToTile.Keys.Contains(offsetCoords)) { HexTile3D tile3d = (HexTile3D)_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); tile3d.Type = HexTile3D.ValidTileTypes[_tileTypeRandom.Next(HexTile3D.ValidTileTypes.Length)]; _coordToTile[offsetCoords] = tile3d; } return _coordToTile[offsetCoords]; } public void SetCenterTile(HexCell cell) { UpdateRects(_hexGrid.GetHexCenter(cell)); } }