GodotComponentTest/scenes/Game.cs

325 lines
13 KiB
C#
Raw Normal View History

using System.Diagnostics;
using Godot;
2022-12-02 21:09:40 +01:00
2023-11-18 22:32:57 +01:00
public class Game : Spatial {
private enum ActionMode {
Default,
Building
}
private ActionMode _actionMode = ActionMode.Default;
private ImageTexture _blackWhitePatternTexture;
private Camera _camera;
private Vector3 _cameraOffset;
private Label _centerLabel;
private HexCell _currentTile;
2022-12-02 21:09:40 +01:00
// ui elements
2022-12-03 20:34:01 +01:00
private Label _framesPerSecondLabel;
2023-06-24 16:59:40 +02:00
private Control _gameUi;
private Label _woodCountLabel;
private Label _goldCountLabel;
private TextureRect _heightTextureRect;
private Button _walkActionButton;
private Button _buildActionButton;
2022-12-02 21:09:40 +01:00
// other members
private HexGrid _hexGrid;
private InteractionSystem _interactionSystem;
private Label _mouseTileCubeLabel;
private Label _mouseTileAxialLabel;
2022-12-02 21:09:40 +01:00
private Spatial _mouseTileHighlight;
private Label _mouseTileOffsetLabel;
private Label _mouseWorldLabel;
private Player _player;
// scene nodes
private Spatial _tileHighlight;
2022-12-04 20:51:02 +01:00
2022-12-02 21:09:40 +01:00
// Resources
private ShaderMaterial _tileMaterial;
private Label _tileOffsetLabel;
private World _world;
private TextureRect _worldTextureRect;
private readonly PackedScene _workbenchScene = GD.Load<PackedScene>("res://entities/Workbench.tscn");
2022-12-02 21:09:40 +01:00
// Called when the node enters the scene tree for the first time.
2023-11-18 22:32:57 +01:00
public override void _Ready() {
2023-06-11 12:45:09 +02:00
// debugStatsContainer
2023-11-15 20:57:25 +01:00
Container debugStatsContainer = (Container)FindNode("DebugStatsContainer");
2023-06-11 12:45:09 +02:00
_framesPerSecondLabel = debugStatsContainer.GetNode<Label>("fps_label");
_centerLabel = debugStatsContainer.GetNode<Label>("center_label");
2023-06-11 12:45:09 +02:00
_tileOffsetLabel = debugStatsContainer.GetNode<Label>("tile_offset_label");
_mouseWorldLabel = debugStatsContainer.GetNode<Label>("mouse_world_label");
2023-08-13 21:08:12 +02:00
_mouseTileOffsetLabel = debugStatsContainer.GetNode<Label>("mouse_tile_offset_label");
_mouseTileCubeLabel = debugStatsContainer.GetNode<Label>("mouse_tile_cube_label");
_mouseTileAxialLabel = debugStatsContainer.GetNode<Label>("mouse_tile_axial_label");
2023-06-11 12:45:09 +02:00
2022-12-02 21:09:40 +01:00
// UI elements
2023-12-14 17:27:07 +01:00
Container worldGeneratorWidget = (Container)FindNode("WorldGeneratorWidget");
_worldTextureRect = worldGeneratorWidget.GetNode<TextureRect>("WorldTextureRect");
_heightTextureRect = worldGeneratorWidget.GetNode<TextureRect>("HeightTextureRect");
2023-06-24 16:59:40 +02:00
_gameUi = (Control)FindNode("GameUI");
_woodCountLabel = _gameUi.GetNode<Label>("TopRight/WoodCount");
Debug.Assert(_woodCountLabel != null);
_goldCountLabel = _gameUi.GetNode<Label>("TopRight/GoldCount");
Debug.Assert(_goldCountLabel != null);
2024-02-28 21:47:40 +01:00
_walkActionButton = _gameUi.GetNode<Button>("Actions/WalkActionButton");
Debug.Assert(_walkActionButton != null);
2024-02-28 21:47:40 +01:00
_buildActionButton = _gameUi.GetNode<Button>("Actions/BuildActionButton");
Debug.Assert(_buildActionButton != null);
2022-12-02 21:09:40 +01:00
// scene nodes
_tileHighlight = GetNode<Spatial>("TileHighlight");
_mouseTileHighlight = GetNode<Spatial>("MouseTileHighlight");
2022-12-02 21:09:40 +01:00
_player = GetNode<Player>("Player");
2023-06-11 12:45:09 +02:00
_camera = (Camera)FindNode("Camera");
_cameraOffset = _camera.GlobalTranslation - _player.GlobalTranslation;
2023-02-12 21:10:28 +01:00
_world = (World)FindNode("World");
2022-12-02 21:09:40 +01:00
// resources
_tileMaterial = GD.Load<ShaderMaterial>("materials/HexTileTextureLookup.tres");
Debug.Assert(_tileMaterial != null);
2022-12-04 20:51:02 +01:00
_blackWhitePatternTexture = new ImageTexture();
2023-11-18 22:32:57 +01:00
Image image = new();
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
_currentTile = new HexCell();
_hexGrid = new HexGrid();
_interactionSystem = GetNode<InteractionSystem>("InteractionSystem");
Debug.Assert(_interactionSystem != null);
2022-12-02 21:09:40 +01:00
// connect signals
2023-08-28 14:01:09 +02:00
_player.TaskQueueComponent.Connect("StartInteraction", _interactionSystem,
nameof(_interactionSystem.OnStartInteraction));
_player.Connect("WoodCountChanged", this, nameof(OnWoodCountChanged));
_player.Connect("GoldCountChanged", this, nameof(OnGoldCountChanged));
2023-11-15 20:57:25 +01:00
_world.Connect("TileClicked", this, nameof(OnTileClicked));
_world.Connect("TileHovered", this, nameof(OnTileHovered));
_world.Connect("OnWorldViewTileTypeImageChanged", this, nameof(OnWorldViewTileTypeImageChanged));
_world.Connect("OnHeightmapImageChanged", this, nameof(OnHeightmapImageChanged));
_walkActionButton.Connect("pressed", this, nameof(OnWalkActionPressed));
_buildActionButton.Connect("pressed", this, nameof(OnBuildActionPressed));
2023-02-12 21:10:28 +01:00
2023-02-12 16:44:48 +01:00
// register entity events
2023-11-18 22:32:57 +01:00
foreach (Node node in GetNode("Entities").GetChildren()) {
if (node.HasSignal("EntityClicked")) {
2023-02-12 16:44:48 +01:00
node.Connect("EntityClicked", this, nameof(OnEntityClicked));
2023-11-18 22:32:57 +01:00
}
}
2023-02-12 21:10:28 +01:00
_world.Connect("EntityClicked", this, nameof(OnEntityClicked));
// perform dependency injection
//_streamContainer.SetWorld(_tileWorld);Clicked
2023-11-15 20:57:25 +01:00
WorldInfoComponent worldInfoComponent = _player.GetNode<WorldInfoComponent>("WorldInfo");
2023-02-12 21:10:28 +01:00
2022-12-04 21:54:44 +01:00
UpdateCurrentTile();
2023-12-14 17:27:07 +01:00
StartNewGame(2, 12);
2022-12-02 21:09:40 +01:00
}
2023-11-18 22:32:57 +01:00
public override void _Input(InputEvent inputEvent) {
if (inputEvent.IsAction("Forward")) {
GD.Print("Forward");
}
2022-12-02 21:09:40 +01:00
2023-11-18 22:32:57 +01:00
if (inputEvent.IsAction("Back")) {
GD.Print("Back");
}
}
2022-12-03 00:43:19 +01:00
2023-12-14 17:27:07 +01:00
public void StartNewGame(int seed, int chunkSize) {
_world.Seed = seed;
_world.ChunkSize = chunkSize;
_world.InitNoiseGenerator();
ResetGame();
2023-12-14 17:27:07 +01:00
_world.UpdateCenterChunkFromPlaneCoord(Vector2.Zero);
}
public void ResetGame() {
_player.GlobalTranslation = Vector3.Zero;
_player.PlaneAngle = -Mathf.Pi * 0.5f;
_world.Reset();
}
2023-11-18 22:32:57 +01:00
public void UpdateCurrentTile() {
// cast a ray from the camera to center
2023-11-15 20:57:25 +01:00
Vector3 cameraNormal = _camera.ProjectRayNormal(_camera.GetViewport().Size * 0.5f);
Vector3 cameraPosition = _camera.ProjectRayOrigin(_camera.GetViewport().Size * 0.5f);
Vector3 cameraDir = cameraNormal - cameraPosition;
Vector3 centerCoord;
2023-11-18 22:32:57 +01:00
if (Mathf.Abs(cameraDir.y) > Globals.EpsPosition) {
centerCoord = cameraPosition + cameraNormal * (-cameraPosition.y / cameraNormal.y);
2023-11-18 22:32:57 +01:00
} else {
centerCoord = _camera.GlobalTranslation;
centerCoord.y = 0;
}
_world.SetCenterPlaneCoord(new Vector2(_player.GlobalTranslation.x, _player.GlobalTranslation.z));
_currentTile = _hexGrid.GetHexAt(new Vector2(centerCoord.x, centerCoord.z));
2022-12-02 21:09:40 +01:00
_centerLabel.Text = centerCoord.ToString("F3");
_tileOffsetLabel.Text = _currentTile.OffsetCoords.ToString();
2022-12-04 21:54:44 +01:00
}
2023-11-18 22:32:57 +01:00
public override void _Process(float delta) {
2022-12-04 21:54:44 +01:00
_framesPerSecondLabel.Text = Engine.GetFramesPerSecond().ToString();
2022-12-02 21:09:40 +01:00
2022-12-04 21:54:44 +01:00
UpdateCurrentTile();
2023-11-15 20:57:25 +01:00
Transform tileHighlightTransform = Transform.Identity;
Vector2 currentTileCenter = _hexGrid.GetHexCenter(_currentTile);
2022-12-02 21:09:40 +01:00
tileHighlightTransform.origin.x = currentTileCenter.x;
tileHighlightTransform.origin.z = currentTileCenter.y;
_tileHighlight.Transform = tileHighlightTransform;
2022-12-03 00:43:19 +01:00
2023-11-15 20:57:25 +01:00
Transform cameraTransform = _camera.Transform;
cameraTransform.origin = _player.GlobalTranslation + _cameraOffset;
_camera.Transform = cameraTransform;
}
public void OnAreaInputEvent(Node camera, InputEvent inputEvent, Vector3 position, Vector3 normal,
2023-11-18 22:32:57 +01:00
int shapeIndex) {
2023-11-15 20:57:25 +01:00
HexCell cellAtCursor = _hexGrid.GetHexAt(new Vector2(position.x, position.z));
Transform highlightTransform = Transform.Identity;
2022-12-02 21:09:40 +01:00
_mouseWorldLabel.Text = position.ToString("F3");
_mouseTileOffsetLabel.Text = cellAtCursor.OffsetCoords.ToString("N");
_mouseTileCubeLabel.Text = cellAtCursor.CubeCoords.ToString("N");
_mouseTileAxialLabel.Text = cellAtCursor.AxialCoords.ToString("N");
2022-12-02 21:09:40 +01:00
_mouseTileHighlight.Transform = highlightTransform;
2022-12-04 20:51:02 +01:00
}
2023-11-18 22:32:57 +01:00
public void OnTileClicked(HexTile3D tile) {
if (_player == null) {
return;
}
2022-12-04 20:51:02 +01:00
if (_actionMode == ActionMode.Building) {
Workbench workbench = (Workbench)_workbenchScene.Instance();
2024-02-28 21:47:40 +01:00
workbench.Connect("EntityClicked", this, nameof(OnEntityClicked));
workbench.Transform = tile.GlobalTransform;
2024-02-28 21:47:40 +01:00
AddChild(workbench);
_world.MarkCellUnwalkable(tile.Cell);
return;
}
2023-11-18 22:32:57 +01:00
if (_player.InteractionComponent != null) {
_player.InteractionComponent.EmitSignal("InteractionEnd");
}
2023-08-28 14:01:09 +02:00
2023-02-12 21:10:28 +01:00
_player.TaskQueueComponent.Reset();
_player.TaskQueueComponent.Queue.Enqueue(new TaskQueueComponent.NavigationTask(
new NavigationPoint(tile.GlobalTranslation)));
2023-05-01 18:37:35 +02:00
}
2023-01-04 22:49:00 +01:00
2023-11-18 22:32:57 +01:00
public void OnTileHovered(HexTile3D tile) {
2023-11-15 20:57:25 +01:00
Transform highlightTransform = tile.GlobalTransform;
_mouseTileHighlight.Transform = highlightTransform;
_mouseWorldLabel.Text = highlightTransform.origin.ToString("F3");
_mouseTileOffsetLabel.Text = tile.OffsetCoords.ToString("N");
_mouseTileCubeLabel.Text = tile.Cell.CubeCoords.ToString("N");
2023-08-28 14:01:09 +02:00
_player.NavigationComponent.FindPath(_player, _player.GlobalTranslation, tile.GlobalTranslation);
}
2023-11-18 22:32:57 +01:00
public void OnEntityClicked(Entity entity) {
2023-01-04 22:49:00 +01:00
GD.Print("Clicked on entity at " + entity.GlobalTranslation);
2023-11-15 20:57:25 +01:00
Spatial mountPoint = (Spatial)entity.FindNode("MountPoint");
2023-11-18 22:32:57 +01:00
if (mountPoint != null) {
2023-02-12 21:10:28 +01:00
_player.TaskQueueComponent.Reset();
_player.TaskQueueComponent.Queue.Enqueue(new TaskQueueComponent.NavigationTask(
new NavigationPoint(mountPoint.GlobalTransform)));
2023-02-12 21:10:28 +01:00
_player.TaskQueueComponent.Queue.Enqueue(new TaskQueueComponent.InteractionTask(entity));
}
2022-12-02 21:09:40 +01:00
}
2023-11-18 22:32:57 +01:00
public void ResetGameState() {
2023-11-15 20:57:25 +01:00
Transform playerStartTransform = Transform.Identity;
playerStartTransform.origin.y = 0;
_player.Transform = playerStartTransform;
_player.TaskQueueComponent.Reset();
_player.NavigationComponent.PlanDirectPath(_player, playerStartTransform.origin, playerStartTransform.origin,
playerStartTransform.basis.Quat());
_woodCountLabel.Text = "0";
2023-06-24 16:59:40 +02:00
_goldCountLabel.Text = "0";
_actionMode = ActionMode.Default;
2023-08-28 14:01:09 +02:00
2023-11-18 22:32:57 +01:00
foreach (Spatial entity in GetNode("Entities").GetChildren()) {
2023-11-15 20:57:25 +01:00
Transform entityTransform = entity.Transform;
2023-11-18 22:32:57 +01:00
Vector2 entityPlanePos = new(entityTransform.origin.x, entityTransform.origin.z);
2023-11-15 20:57:25 +01:00
Vector2 entityOffsetCoordinates = _hexGrid.GetHexAt(entityPlanePos).OffsetCoords;
entityTransform.origin.y = 0;
entity.Transform = entityTransform;
}
}
2023-11-18 22:32:57 +01:00
private void OnHeightmapImageChanged(Image heightmapImage) {
ImageTexture newHeightmapTexture = new();
newHeightmapTexture.CreateFromImage(heightmapImage,
(uint)(Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
_heightTextureRect.Texture = newHeightmapTexture;
}
2023-11-18 22:32:57 +01:00
private void OnWorldViewTileTypeImageChanged(Image viewTileTypeImage) {
ImageTexture newWorldTexture = new();
newWorldTexture.CreateFromImage(viewTileTypeImage,
(uint)(Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
_worldTextureRect.Texture = newWorldTexture;
_tileMaterial.SetShaderParam("MapAlbedoTexture", newWorldTexture);
_tileMaterial.SetShaderParam("TextureSize", (int)newWorldTexture.GetSize().x);
2023-11-01 17:59:43 +01:00
_tileMaterial.SetShaderParam("CoordinateOffsetU", (int)_world.WorldTextureCoordinateOffset.x);
_tileMaterial.SetShaderParam("CoordinateOffsetV", (int)_world.WorldTextureCoordinateOffset.y);
}
public void OnWoodCountChanged(int woodCount) {
AnimationPlayer animationPlayer = _woodCountLabel.GetNode<AnimationPlayer>("AnimationPlayer");
_woodCountLabel.Text = woodCount.ToString();
animationPlayer.CurrentAnimation = "FlashLabel";
animationPlayer.Seek(0);
animationPlayer.Play();
}
2023-11-18 22:32:57 +01:00
public void OnGoldCountChanged(int goldCount) {
AnimationPlayer animationPlayer = _goldCountLabel.GetNode<AnimationPlayer>("AnimationPlayer");
_goldCountLabel.Text = goldCount.ToString();
2023-06-24 16:59:40 +02:00
animationPlayer.CurrentAnimation = "FlashLabel";
animationPlayer.Seek(0);
animationPlayer.Play();
}
public void OnWalkActionPressed() {
_actionMode = ActionMode.Default;
}
public void OnBuildActionPressed() {
_actionMode = ActionMode.Building;
}
2022-12-02 21:09:40 +01:00
}