2022-12-02 21:09:40 +01:00
|
|
|
using Godot;
|
2022-12-28 16:22:53 +01:00
|
|
|
using System.Diagnostics;
|
2022-12-02 21:09:40 +01:00
|
|
|
using System.Linq;
|
|
|
|
using Array = Godot.Collections.Array;
|
|
|
|
|
2023-02-12 16:30:56 +01:00
|
|
|
public class Game : Spatial
|
2022-12-02 21:09:40 +01:00
|
|
|
{
|
|
|
|
// ui elements
|
2022-12-03 20:34:01 +01:00
|
|
|
private Label _framesPerSecondLabel;
|
2022-12-02 21:09:40 +01:00
|
|
|
private Label _tileLabel;
|
|
|
|
private Label _tileOffsetLabel;
|
|
|
|
private Label _numTilesLabel;
|
|
|
|
private Label _mouseWorldLabel;
|
|
|
|
private Label _mouseTileLabel;
|
2022-12-03 20:34:01 +01:00
|
|
|
private Label _numCoordsAddedLabel;
|
|
|
|
private Label _numCoordsRemovedLabel;
|
2022-12-28 16:22:53 +01:00
|
|
|
private TextureRect _worldTextureRect;
|
2023-05-20 21:36:32 +02:00
|
|
|
private TextureRect _heightTextureRect;
|
2023-05-05 16:26:33 +02:00
|
|
|
private Button _generateWorldButton;
|
2022-12-02 21:09:40 +01:00
|
|
|
|
|
|
|
// scene nodes
|
|
|
|
private Spatial _tileHighlight;
|
|
|
|
private Spatial _mouseTileHighlight;
|
2022-12-03 00:43:19 +01:00
|
|
|
private StreamContainer _streamContainer;
|
2022-12-02 21:09:40 +01:00
|
|
|
private Area _streamContainerArea;
|
2022-12-03 00:43:19 +01:00
|
|
|
private Spatial _streamContainerActiveTiles;
|
2022-12-02 21:09:40 +01:00
|
|
|
private Player _player;
|
2023-01-04 22:49:00 +01:00
|
|
|
private Chest _chest;
|
2022-12-28 16:22:53 +01:00
|
|
|
private TileWorld _tileWorld;
|
2023-02-12 16:55:30 +01:00
|
|
|
private Camera _camera;
|
2022-12-04 20:51:02 +01:00
|
|
|
|
2022-12-02 21:09:40 +01:00
|
|
|
// Resources
|
|
|
|
private PackedScene _tileHighlightScene;
|
2023-05-09 21:51:45 +02:00
|
|
|
private ShaderMaterial _tileMaterial;
|
2022-12-04 20:51:02 +01:00
|
|
|
|
2022-12-02 21:09:40 +01:00
|
|
|
// other members
|
|
|
|
private HexGrid _hexGrid;
|
|
|
|
private HexCell _lastTile;
|
|
|
|
private HexCell _currentTile;
|
2023-02-12 16:55:30 +01:00
|
|
|
private Vector3 _cameraOffset;
|
2023-05-11 22:26:06 +02:00
|
|
|
private ImageTexture _blackWhitePatternTexture;
|
2022-12-02 21:09:40 +01:00
|
|
|
|
|
|
|
// Called when the node enters the scene tree for the first time.
|
|
|
|
public override void _Ready()
|
|
|
|
{
|
2023-06-11 12:45:09 +02:00
|
|
|
// debugStatsContainer
|
|
|
|
Container debugStatsContainer = (Container) FindNode("DebugStatsContainer");
|
|
|
|
|
|
|
|
_framesPerSecondLabel = debugStatsContainer.GetNode<Label>("fps_label");
|
|
|
|
_tileLabel = debugStatsContainer.GetNode<Label>("tile_label");
|
|
|
|
_tileOffsetLabel = debugStatsContainer.GetNode<Label>("tile_offset_label");
|
|
|
|
_numTilesLabel = debugStatsContainer.GetNode<Label>("num_tiles_label");
|
|
|
|
_mouseWorldLabel = debugStatsContainer.GetNode<Label>("mouse_world_label");
|
|
|
|
_mouseTileLabel = debugStatsContainer.GetNode<Label>("mouse_tile_label");
|
|
|
|
_numCoordsAddedLabel = debugStatsContainer.GetNode<Label>("num_coords_added_label");
|
|
|
|
_numCoordsRemovedLabel = debugStatsContainer.GetNode<Label>("num_coords_removed_label");
|
|
|
|
|
2022-12-02 21:09:40 +01:00
|
|
|
// UI elements
|
2023-06-11 12:45:09 +02:00
|
|
|
Container worldGeneratorContainer = (Container)FindNode("WorldGeneratorContainer");
|
|
|
|
_worldTextureRect = worldGeneratorContainer.GetNode<TextureRect>("WorldTextureRect");
|
|
|
|
_heightTextureRect = worldGeneratorContainer.GetNode<TextureRect>("HeightTextureRect");
|
|
|
|
_generateWorldButton = worldGeneratorContainer.GetNode<Button>("WorldGenerateButton");
|
2022-12-02 21:09:40 +01:00
|
|
|
|
|
|
|
// scene nodes
|
|
|
|
_tileHighlight = GetNode<Spatial>("TileHighlight");
|
|
|
|
_mouseTileHighlight = GetNode<Spatial>("MouseTileHighlight");
|
2023-06-11 12:45:09 +02:00
|
|
|
|
|
|
|
_streamContainer = (StreamContainer)FindNode("StreamContainer");
|
|
|
|
_streamContainerArea = _streamContainer.GetNode<Area>("Area");
|
|
|
|
_streamContainerActiveTiles = _streamContainer.GetNode<Spatial>("ActiveTiles");
|
|
|
|
|
2022-12-02 21:09:40 +01:00
|
|
|
_player = GetNode<Player>("Player");
|
2023-02-12 16:30:56 +01:00
|
|
|
_chest = GetNode<Chest>("Entities/Chest");
|
2022-12-28 16:22:53 +01:00
|
|
|
_tileWorld = GetNode<TileWorld>("TileWorld");
|
2023-06-11 12:45:09 +02:00
|
|
|
_camera = (Camera)FindNode("Camera");
|
2023-02-12 16:55:30 +01:00
|
|
|
_cameraOffset = _camera.GlobalTranslation - _player.GlobalTranslation;
|
2023-02-12 21:10:28 +01:00
|
|
|
|
2023-06-11 13:28:33 +02:00
|
|
|
// populate UI values
|
|
|
|
Slider generatorWorldSizeSlider = worldGeneratorContainer.GetNode<Slider>("HBoxContainer/WorldSizeSlider");
|
|
|
|
generatorWorldSizeSlider.Value = _tileWorld.Size;
|
|
|
|
|
2022-12-28 16:22:53 +01:00
|
|
|
Debug.Assert(_tileWorld != null);
|
2022-12-02 21:09:40 +01:00
|
|
|
|
|
|
|
// resources
|
|
|
|
_tileHighlightScene = GD.Load<PackedScene>("utils/TileHighlight.tscn");
|
2023-05-09 21:51:45 +02:00
|
|
|
_tileMaterial = GD.Load<ShaderMaterial>("materials/HexTileTextureLookup.tres");
|
|
|
|
Debug.Assert(_tileMaterial != null);
|
2022-12-04 20:51:02 +01:00
|
|
|
|
2023-05-11 22:26:06 +02:00
|
|
|
_blackWhitePatternTexture = new ImageTexture();
|
|
|
|
Image image = new Image();
|
|
|
|
image.Load("assets/4x4checker.png");
|
|
|
|
_blackWhitePatternTexture.CreateFromImage(image, (uint) (Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
|
|
|
|
|
2022-12-02 21:09:40 +01:00
|
|
|
// other members
|
|
|
|
_lastTile = new HexCell();
|
|
|
|
_currentTile = new HexCell();
|
|
|
|
_hexGrid = new HexGrid();
|
|
|
|
|
2022-12-28 16:22:53 +01:00
|
|
|
// update data
|
2023-05-20 12:27:30 +02:00
|
|
|
_worldTextureRect.RectSize = Vector2.One * _tileWorld.Size;
|
2023-05-20 21:36:32 +02:00
|
|
|
_heightTextureRect.RectSize = Vector2.One * _tileWorld.Size;
|
2023-02-12 21:10:28 +01:00
|
|
|
|
2022-12-02 21:09:40 +01:00
|
|
|
// connect signals
|
2022-12-04 20:51:02 +01:00
|
|
|
_streamContainerArea.Connect("input_event", this, nameof(OnAreaInputEvent));
|
2023-01-04 22:49:00 +01:00
|
|
|
_streamContainer.Connect("TileClicked", this, nameof(OnTileClicked));
|
2023-05-09 21:51:45 +02:00
|
|
|
_streamContainer.Connect("TileHovered", this, nameof(OnTileHovered));
|
2022-12-28 16:22:53 +01:00
|
|
|
_tileWorld.Connect("WorldGenerated", this, nameof(OnWorldGenerated));
|
2023-05-05 16:26:33 +02:00
|
|
|
_generateWorldButton.Connect("pressed", this, nameof(OnGenerateButton));
|
2023-02-12 21:10:28 +01:00
|
|
|
|
2023-02-12 16:44:48 +01:00
|
|
|
// register entity events
|
|
|
|
Array entityNodes = FindNode("Entities").GetChildren();
|
|
|
|
foreach (Node node in entityNodes)
|
|
|
|
{
|
|
|
|
if (node is Chest)
|
|
|
|
{
|
|
|
|
node.Connect("EntityClicked", this, nameof(OnEntityClicked));
|
|
|
|
}
|
|
|
|
}
|
2023-02-12 21:10:28 +01:00
|
|
|
|
2022-12-28 16:22:53 +01:00
|
|
|
// perform dependency injection
|
2023-05-09 21:51:45 +02:00
|
|
|
//_streamContainer.SetWorld(_tileWorld);Clicked
|
2022-12-28 16:22:53 +01:00
|
|
|
WorldInfoComponent worldInfoComponent = _player.GetNode<WorldInfoComponent>("WorldInfo");
|
|
|
|
if (worldInfoComponent != null)
|
|
|
|
{
|
|
|
|
worldInfoComponent.SetWorld(_tileWorld);
|
|
|
|
}
|
2023-02-12 21:10:28 +01:00
|
|
|
|
2023-06-10 17:09:24 +02:00
|
|
|
_tileWorld.Generate(_tileWorld.Size);
|
2022-12-04 21:54:44 +01:00
|
|
|
UpdateCurrentTile();
|
|
|
|
_streamContainer.SetCenterTile(_currentTile);
|
2022-12-02 21:09:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public void CreateTileGrid()
|
|
|
|
{
|
|
|
|
foreach (int x_index in Enumerable.Range(-3, 6))
|
|
|
|
{
|
|
|
|
foreach (int y_index in Enumerable.Range(0, 1))
|
|
|
|
{
|
|
|
|
var tile = (Spatial)_tileHighlightScene.Instance();
|
|
|
|
HexCell cell = new HexCell();
|
|
|
|
Vector2 planeCoords = _hexGrid.GetHexCenterFromOffset(new Vector2(x_index, y_index));
|
|
|
|
Transform tileTransform = Transform.Identity;
|
|
|
|
tileTransform.origin.x = planeCoords.x;
|
|
|
|
tileTransform.origin.z = planeCoords.y;
|
|
|
|
tile.Transform = tileTransform;
|
|
|
|
AddChild(tile);
|
|
|
|
GD.Print("Added tile at offset coords " + new Vector2(x_index, y_index).ToString() +
|
|
|
|
" and world coords " + tileTransform.origin.ToString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-03 00:43:19 +01:00
|
|
|
|
2022-12-04 21:54:44 +01:00
|
|
|
public void UpdateCurrentTile()
|
2022-12-02 21:09:40 +01:00
|
|
|
{
|
2023-06-11 13:22:13 +02:00
|
|
|
// cast a ray from the camera to center
|
|
|
|
Vector3 cameraNormal = _camera.ProjectRayNormal(_camera.GetViewport().Size * 0.5f);
|
|
|
|
Vector3 cameraPosition = _camera.ProjectRayOrigin(_camera.GetViewport().Size * 0.5f);
|
|
|
|
Vector3 cameraDir = cameraNormal - cameraPosition;
|
|
|
|
|
|
|
|
Vector3 centerCoord;
|
|
|
|
|
|
|
|
if (Mathf.Abs(cameraDir.y) > Globals.EpsPosition)
|
|
|
|
{
|
|
|
|
centerCoord = cameraPosition + cameraNormal * (-cameraPosition.y / cameraNormal.y);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
centerCoord = _camera.GlobalTranslation;
|
|
|
|
centerCoord.y = 0;
|
|
|
|
}
|
|
|
|
|
2022-12-28 16:22:53 +01:00
|
|
|
|
2023-06-11 13:22:13 +02:00
|
|
|
_currentTile = _hexGrid.GetHexAt(new Vector2(centerCoord.x, centerCoord.z));
|
2022-12-02 21:09:40 +01:00
|
|
|
|
2023-06-11 13:22:13 +02:00
|
|
|
_tileLabel.Text = centerCoord.ToString();
|
|
|
|
_tileOffsetLabel.Text = _currentTile.OffsetCoords.ToString();
|
2022-12-04 21:54:44 +01:00
|
|
|
}
|
|
|
|
|
2022-12-28 16:22:53 +01:00
|
|
|
|
2022-12-04 21:54:44 +01:00
|
|
|
public override void _Process(float delta)
|
|
|
|
{
|
|
|
|
_framesPerSecondLabel.Text = Engine.GetFramesPerSecond().ToString();
|
|
|
|
_lastTile = _currentTile;
|
2022-12-02 21:09:40 +01:00
|
|
|
|
2022-12-04 21:54:44 +01:00
|
|
|
UpdateCurrentTile();
|
2022-12-28 16:22:53 +01:00
|
|
|
|
2022-12-02 21:09:40 +01:00
|
|
|
Transform tileHighlightTransform = Transform.Identity;
|
|
|
|
Vector2 currentTileCenter = _hexGrid.GetHexCenter(_currentTile);
|
|
|
|
tileHighlightTransform.origin.x = currentTileCenter.x;
|
|
|
|
tileHighlightTransform.origin.z = currentTileCenter.y;
|
|
|
|
_tileHighlight.Transform = tileHighlightTransform;
|
2022-12-03 00:43:19 +01:00
|
|
|
|
|
|
|
if (_currentTile.CubeCoords != _lastTile.CubeCoords)
|
|
|
|
{
|
|
|
|
_streamContainer.SetCenterTile(_currentTile);
|
|
|
|
|
|
|
|
_numTilesLabel.Text = _streamContainerActiveTiles.GetChildCount().ToString();
|
2022-12-03 20:34:01 +01:00
|
|
|
_numCoordsAddedLabel.Text = _streamContainer.AddedCoords.Count.ToString();
|
|
|
|
_numCoordsRemovedLabel.Text = _streamContainer.RemovedCoords.Count.ToString();
|
2022-12-03 00:43:19 +01:00
|
|
|
}
|
2022-12-02 21:09:40 +01:00
|
|
|
|
2023-02-12 16:55:30 +01:00
|
|
|
Transform cameraTransform = _camera.Transform;
|
|
|
|
cameraTransform.origin = _player.GlobalTranslation + _cameraOffset;
|
2023-06-10 17:09:24 +02:00
|
|
|
// _camera.Transform = cameraTransform;
|
2023-02-12 16:55:30 +01:00
|
|
|
}
|
2022-12-28 16:22:53 +01:00
|
|
|
|
2023-05-05 16:26:33 +02:00
|
|
|
|
|
|
|
public void OnGenerateButton()
|
|
|
|
{
|
|
|
|
GD.Print("Generating");
|
2023-06-10 17:09:24 +02:00
|
|
|
Slider worldSizeSlider = (Slider)FindNode("WorldSizeSlider");
|
|
|
|
if (worldSizeSlider == null)
|
|
|
|
{
|
|
|
|
GD.PrintErr("Could not find WorldSizeSlider!");
|
|
|
|
return;
|
|
|
|
}
|
2023-05-05 16:26:33 +02:00
|
|
|
_tileWorld.Seed = _tileWorld.Seed + 1;
|
2023-06-10 17:09:24 +02:00
|
|
|
_tileWorld.Generate((int)worldSizeSlider.Value);
|
2023-05-05 16:26:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-12-28 16:22:53 +01:00
|
|
|
public void OnAreaInputEvent(Node camera, InputEvent inputEvent, Vector3 position, Vector3 normal,
|
|
|
|
int shapeIndex)
|
2022-12-02 21:09:40 +01:00
|
|
|
{
|
|
|
|
HexCell cellAtCursor = _hexGrid.GetHexAt(new Vector2(position.x, position.z));
|
|
|
|
Transform highlightTransform = Transform.Identity;
|
|
|
|
|
|
|
|
_mouseWorldLabel.Text = position.ToString();
|
|
|
|
_mouseTileLabel.Text = cellAtCursor.OffsetCoords.ToString();
|
|
|
|
_mouseTileHighlight.Transform = highlightTransform;
|
2022-12-03 20:34:01 +01:00
|
|
|
|
2023-02-12 21:10:28 +01:00
|
|
|
if (inputEvent is InputEventMouseButton && ((InputEventMouseButton)inputEvent).Pressed)
|
2022-12-03 20:34:01 +01:00
|
|
|
{
|
2023-01-04 22:49:00 +01:00
|
|
|
_streamContainer.EmitSignal("TileClicked", _streamContainer.GetTile3dAt(cellAtCursor.OffsetCoords));
|
2022-12-04 20:51:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-28 16:22:53 +01:00
|
|
|
|
2023-01-04 22:49:00 +01:00
|
|
|
public void OnTileClicked(HexTile3D tile)
|
2022-12-04 20:51:02 +01:00
|
|
|
{
|
|
|
|
if (_player == null)
|
|
|
|
{
|
|
|
|
return;
|
2022-12-03 20:34:01 +01:00
|
|
|
}
|
2022-12-04 20:51:02 +01:00
|
|
|
|
2023-02-12 21:10:28 +01:00
|
|
|
_player.TaskQueueComponent.Reset();
|
|
|
|
_player.TaskQueueComponent.Queue.Enqueue(new TaskQueueComponent.NavigationTask(
|
|
|
|
new NavigationComponent.NavigationPoint(tile.GlobalTranslation)));
|
2023-05-01 18:37:35 +02:00
|
|
|
}
|
2023-01-04 22:49:00 +01:00
|
|
|
|
2023-05-09 21:51:45 +02:00
|
|
|
public void OnTileHovered(HexTile3D tile)
|
|
|
|
{
|
2023-06-11 20:03:55 +02:00
|
|
|
Transform highlightTransform = tile.GlobalTransform;
|
|
|
|
highlightTransform.origin.y += 0.1f;
|
2023-05-09 21:51:45 +02:00
|
|
|
_mouseTileHighlight.Transform = highlightTransform;
|
|
|
|
_mouseWorldLabel.Text = tile.GlobalTranslation.ToString();
|
|
|
|
_mouseTileLabel.Text = tile.OffsetCoords.ToString();
|
|
|
|
}
|
|
|
|
|
2023-01-04 22:49:00 +01:00
|
|
|
public void OnEntityClicked(Entity entity)
|
|
|
|
{
|
|
|
|
GD.Print("Clicked on entity at " + entity.GlobalTranslation);
|
2023-02-12 16:30:56 +01:00
|
|
|
|
|
|
|
Spatial mountPoint = (Spatial)entity.FindNode("MountPoint");
|
|
|
|
if (mountPoint != null)
|
|
|
|
{
|
2023-02-12 21:10:28 +01:00
|
|
|
_player.TaskQueueComponent.Reset();
|
|
|
|
_player.TaskQueueComponent.Queue.Enqueue(new TaskQueueComponent.NavigationTask(
|
|
|
|
new NavigationComponent.NavigationPoint(mountPoint.GlobalTransform)));
|
|
|
|
_player.TaskQueueComponent.Queue.Enqueue(new TaskQueueComponent.InteractionTask(entity));
|
2023-02-12 16:30:56 +01:00
|
|
|
}
|
2022-12-02 21:09:40 +01:00
|
|
|
}
|
2022-12-28 16:22:53 +01:00
|
|
|
|
|
|
|
|
2023-05-21 17:24:37 +02:00
|
|
|
public void ResetGameState()
|
|
|
|
{
|
|
|
|
Transform playerStartTransform = Transform.Identity;
|
|
|
|
float height = _tileWorld.GetHeightAtOffset(new Vector2(0, 0));
|
|
|
|
playerStartTransform.origin.y = height;
|
|
|
|
_player.Transform = playerStartTransform;
|
|
|
|
_player.TaskQueueComponent.Reset();
|
|
|
|
_player.Navigation.PlanDirectPath(playerStartTransform.origin, playerStartTransform.origin, playerStartTransform.basis.Quat());
|
2023-05-21 17:29:44 +02:00
|
|
|
|
|
|
|
foreach (Spatial entity in GetNode("Entities").GetChildren())
|
|
|
|
{
|
|
|
|
Transform entityTransform = entity.Transform;
|
|
|
|
Vector2 entityPlanePos = new Vector2(entityTransform.origin.x, entityTransform.origin.z);
|
|
|
|
Vector2 entityOffsetCoordinates = _hexGrid.GetHexAt(entityPlanePos).OffsetCoords;
|
|
|
|
float entityHeight = _tileWorld.GetHeightAtOffset(entityOffsetCoordinates);
|
|
|
|
entityTransform.origin.y = entityHeight;
|
|
|
|
entity.Transform = entityTransform;
|
|
|
|
}
|
2023-05-21 17:24:37 +02:00
|
|
|
}
|
|
|
|
|
2022-12-28 16:22:53 +01:00
|
|
|
public void OnWorldGenerated()
|
|
|
|
{
|
2023-06-10 17:09:24 +02:00
|
|
|
GD.Print("Using new map. Size: " + (int)_tileWorld.Colormap.GetSize().x);
|
2023-05-21 17:24:37 +02:00
|
|
|
|
2023-05-20 21:36:32 +02:00
|
|
|
ImageTexture newWorldTexture = new ImageTexture();
|
|
|
|
newWorldTexture.CreateFromImage(_tileWorld.Colormap, (uint) (Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
|
|
|
|
_worldTextureRect.Texture = newWorldTexture;
|
|
|
|
_tileMaterial.SetShaderParam("MapAlbedoTexture", newWorldTexture);
|
2023-05-11 22:26:06 +02:00
|
|
|
_tileMaterial.SetShaderParam("TextureSize", (int)_tileWorld.Colormap.GetSize().x);
|
|
|
|
|
2023-05-21 17:24:37 +02:00
|
|
|
ImageTexture newHeightTexture = new ImageTexture();
|
|
|
|
newHeightTexture.CreateFromImage(_tileWorld.Heightmap, (uint) (Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
|
2023-05-20 21:36:32 +02:00
|
|
|
_heightTextureRect.Texture = newHeightTexture;
|
|
|
|
|
2023-05-13 09:29:54 +02:00
|
|
|
_streamContainer.OnWorldGenerated();
|
2023-05-20 12:27:30 +02:00
|
|
|
|
|
|
|
// Reset player transform to offset 0,0 and at current height
|
2023-05-21 17:24:37 +02:00
|
|
|
ResetGameState();
|
2022-12-28 16:22:53 +01:00
|
|
|
}
|
2022-12-02 21:09:40 +01:00
|
|
|
}
|