Intermediate commit

main
Martin Felis 2023-12-14 17:27:07 +01:00
parent bfd5eef2f5
commit cfb731c27e
16 changed files with 420 additions and 168 deletions

View File

@ -21,7 +21,7 @@ compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=true
flags/repeat=1
flags/filter=false
flags/mipmaps=true
flags/anisotropic=false

View File

@ -19,7 +19,7 @@ compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=2
flags/repeat=true
flags/repeat=0
flags/filter=false
flags/mipmaps=true
flags/anisotropic=false

View File

@ -2,28 +2,30 @@
importer="texture"
type="StreamTexture"
path="res://.import/IslandMask2.png-b09deb1a0f8633d5ff352ae53948f6ed.stex"
path.s3tc="res://.import/IslandMask2.png-b09deb1a0f8633d5ff352ae53948f6ed.s3tc.stex"
path.etc2="res://.import/IslandMask2.png-b09deb1a0f8633d5ff352ae53948f6ed.etc2.stex"
metadata={
"vram_texture": false
"imported_formats": [ "s3tc", "etc2" ],
"vram_texture": true
}
[deps]
source_file="res://assets/IslandMasks/IslandMask2.png"
dest_files=[ "res://.import/IslandMask2.png-b09deb1a0f8633d5ff352ae53948f6ed.stex" ]
dest_files=[ "res://.import/IslandMask2.png-b09deb1a0f8633d5ff352ae53948f6ed.s3tc.stex", "res://.import/IslandMask2.png-b09deb1a0f8633d5ff352ae53948f6ed.etc2.stex" ]
[params]
compress/mode=0
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/repeat=true
flags/filter=true
flags/mipmaps=false
flags/mipmaps=true
flags/anisotropic=false
flags/srgb=2
flags/srgb=1
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
@ -31,5 +33,5 @@ process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
detect_3d=false
svg/scale=1.0

View File

@ -79,7 +79,7 @@ public class NavigationComponent : Spatial {
}
// Perform smoothing
_planningPathSmoothedWorldNavigationPoints = SmoothPath(entity, _planningPathWorldNavigationPoints);
_planningPathSmoothedWorldNavigationPoints = World.SmoothPath(entity, _planningPathWorldNavigationPoints);
// Ensure starting point is the current position
if (_planningPathSmoothedWorldNavigationPoints.Count > 0) {
@ -90,11 +90,9 @@ public class NavigationComponent : Spatial {
public void FindPath(Entity entity, Vector3 fromPositionWorld, NavigationPoint navigationPoint) {
FindPath(entity, fromPositionWorld, navigationPoint.WorldPosition);
if (_planningPathSmoothedWorldNavigationPoints.Count > 0) {
_planningPathWorldNavigationPoints[_planningPathWorldNavigationPoints.Count - 1] = navigationPoint;
_planningPathSmoothedWorldNavigationPoints[_planningPathSmoothedWorldNavigationPoints.Count - 1] =
navigationPoint;
}
_planningPathWorldNavigationPoints[_planningPathWorldNavigationPoints.Count - 1] = navigationPoint;
_planningPathSmoothedWorldNavigationPoints[_planningPathSmoothedWorldNavigationPoints.Count - 1] =
navigationPoint;
}
public void PlanGridPath(Entity entity, Vector3 fromPositionWorld, Vector3 toPositionWorld) {

View File

@ -44,6 +44,7 @@ public class Tree : StaticBody, IInteractionInterface {
if (_health == 0) {
InteractionComponent.EndInteraction();
InteractionComponent.TargetEntity = null;
GD.Print("Tree chopped!");
EmitSignal("TreeChopped", this);
}
}

View File

@ -134,5 +134,9 @@ common/enable_pause_aware_picking=true
quality/directional_shadow/size.mobile=512
quality/shadow_atlas/size.mobile=1024
quality/shadow_atlas/quadrant_0_subdiv=0
quality/shadow_atlas/quadrant_1_subdiv=0
quality/shadow_atlas/quadrant_2_subdiv=0
quality/shadow_atlas/quadrant_3_subdiv=0
quality/subsurface_scattering/quality=0
environment/default_environment="res://default_env.tres"

View File

@ -12,29 +12,23 @@ public class Game : Spatial {
// ui elements
private Label _framesPerSecondLabel;
private Control _gameUi;
private Button _generateWorldButton;
private Label _goldCountLabel;
private TextureRect _heightTextureRect;
// other members
private HexGrid _hexGrid;
private InteractionSystem _interactionSystem;
private HexCell _lastTile;
private Label _mouseTileCubeLabel;
private Label _mouseTileAxialLabel;
private Spatial _mouseTileHighlight;
private Label _mouseTileOffsetLabel;
private Label _mouseWorldLabel;
private Label _numCoordsAddedLabel;
private Label _numCoordsRemovedLabel;
private Label _numTilesLabel;
private Player _player;
// scene nodes
private Spatial _tileHighlight;
// Resources
private PackedScene _tileHighlightScene;
private ShaderMaterial _tileMaterial;
private Label _tileOffsetLabel;
private World _world;
@ -48,19 +42,15 @@ public class Game : Spatial {
_framesPerSecondLabel = debugStatsContainer.GetNode<Label>("fps_label");
_centerLabel = debugStatsContainer.GetNode<Label>("center_label");
_tileOffsetLabel = debugStatsContainer.GetNode<Label>("tile_offset_label");
_numTilesLabel = debugStatsContainer.GetNode<Label>("num_tiles_label");
_mouseWorldLabel = debugStatsContainer.GetNode<Label>("mouse_world_label");
_mouseTileOffsetLabel = debugStatsContainer.GetNode<Label>("mouse_tile_offset_label");
_mouseTileCubeLabel = debugStatsContainer.GetNode<Label>("mouse_tile_cube_label");
_mouseTileAxialLabel = debugStatsContainer.GetNode<Label>("mouse_tile_axial_label");
_numCoordsAddedLabel = debugStatsContainer.GetNode<Label>("num_coords_added_label");
_numCoordsRemovedLabel = debugStatsContainer.GetNode<Label>("num_coords_removed_label");
// UI elements
Container worldGeneratorContainer = (Container)FindNode("WorldGeneratorContainer");
_worldTextureRect = worldGeneratorContainer.GetNode<TextureRect>("WorldTextureRect");
_heightTextureRect = worldGeneratorContainer.GetNode<TextureRect>("HeightTextureRect");
_generateWorldButton = worldGeneratorContainer.GetNode<Button>("WorldGenerateButton");
Container worldGeneratorWidget = (Container)FindNode("WorldGeneratorWidget");
_worldTextureRect = worldGeneratorWidget.GetNode<TextureRect>("WorldTextureRect");
_heightTextureRect = worldGeneratorWidget.GetNode<TextureRect>("HeightTextureRect");
_gameUi = (Control)FindNode("GameUI");
_goldCountLabel = _gameUi.GetNode<Label>("GoldCount");
Debug.Assert(_goldCountLabel != null);
@ -75,11 +65,7 @@ public class Game : Spatial {
_world = (World)FindNode("World");
// populate UI values
Slider generatorWorldSizeSlider = worldGeneratorContainer.GetNode<Slider>("HBoxContainer/WorldSizeSlider");
// resources
_tileHighlightScene = GD.Load<PackedScene>("utils/TileHighlight.tscn");
_tileMaterial = GD.Load<ShaderMaterial>("materials/HexTileTextureLookup.tres");
Debug.Assert(_tileMaterial != null);
@ -89,14 +75,12 @@ public class Game : Spatial {
_blackWhitePatternTexture.CreateFromImage(image, (uint)(Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
// other members
_lastTile = new HexCell();
_currentTile = new HexCell();
_hexGrid = new HexGrid();
_interactionSystem = GetNode<InteractionSystem>("InteractionSystem");
Debug.Assert(_interactionSystem != null);
// connect signals
_generateWorldButton.Connect("pressed", this, nameof(OnGenerateButton));
_player.TaskQueueComponent.Connect("StartInteraction", _interactionSystem,
nameof(_interactionSystem.OnStartInteraction));
_player.Connect("GoldCountChanged", this, nameof(OnGoldCountChanged));
@ -119,6 +103,8 @@ public class Game : Spatial {
WorldInfoComponent worldInfoComponent = _player.GetNode<WorldInfoComponent>("WorldInfo");
UpdateCurrentTile();
StartNewGame(123, 12);
}
@ -132,6 +118,23 @@ public class Game : Spatial {
}
}
public void StartNewGame(int seed, int chunkSize) {
_world.Seed = seed;
_world.ChunkSize = chunkSize;
_world.InitNoiseGenerator();
ResetGame();
_world.UpdateCenterChunkFromPlaneCoord(Vector2.Zero);
}
public void ResetGame() {
_player.GlobalTranslation = Vector3.Zero;
_player.PlaneAngle = -Mathf.Pi * 0.5f;
_world.Reset();
}
public void UpdateCurrentTile() {
// cast a ray from the camera to center
Vector3 cameraNormal = _camera.ProjectRayNormal(_camera.GetViewport().Size * 0.5f);
@ -158,7 +161,6 @@ public class Game : Spatial {
public override void _Process(float delta) {
_framesPerSecondLabel.Text = Engine.GetFramesPerSecond().ToString();
_lastTile = _currentTile;
UpdateCurrentTile();
@ -173,16 +175,6 @@ public class Game : Spatial {
_camera.Transform = cameraTransform;
}
public void OnGenerateButton() {
GD.Print("Generating");
Slider worldSizeSlider = (Slider)FindNode("WorldSizeSlider");
if (worldSizeSlider == null) {
GD.PrintErr("Could not find WorldSizeSlider!");
}
}
public void OnAreaInputEvent(Node camera, InputEvent inputEvent, Vector3 position, Vector3 normal,
int shapeIndex) {
HexCell cellAtCursor = _hexGrid.GetHexAt(new Vector2(position.x, position.z));

View File

@ -1,22 +1,16 @@
[gd_scene load_steps=21 format=2]
[gd_scene load_steps=14 format=2]
[ext_resource path="res://ui/WorldGeneratorWidget.gd" type="Script" id=1]
[ext_resource path="res://entities/Player.tscn" type="PackedScene" id=2]
[ext_resource path="res://scenes/Camera.tscn" type="PackedScene" id=3]
[ext_resource path="res://ui/EditorUI.tscn" type="PackedScene" id=4]
[ext_resource path="res://utils/TileHighlight.tscn" type="PackedScene" id=5]
[ext_resource path="res://ui/DebugStatsContainer.gd" type="Script" id=6]
[ext_resource path="res://scenes/World.cs" type="Script" id=7]
[ext_resource path="res://scenes/World.tscn" type="PackedScene" id=7]
[ext_resource path="res://scenes/Game.cs" type="Script" id=9]
[ext_resource path="res://entities/Chest.tscn" type="PackedScene" id=11]
[ext_resource path="res://ui/WorldGeneratorUI.gd" type="Script" id=12]
[ext_resource path="res://assets/Environment/HexTileMesh.tres" type="CylinderMesh" id=13]
[ext_resource path="res://entities/Axe.tscn" type="PackedScene" id=14]
[ext_resource path="res://systems/InteractionSystem.cs" type="Script" id=15]
[ext_resource path="res://entities/rockA.tscn" type="PackedScene" id=16]
[ext_resource path="res://entities/rockC.tscn" type="PackedScene" id=17]
[ext_resource path="res://entities/rockB.tscn" type="PackedScene" id=18]
[ext_resource path="res://entities/Tree.tscn" type="PackedScene" id=19]
[ext_resource path="res://assets/Environment/grassLarge.tscn" type="PackedScene" id=20]
[sub_resource type="Animation" id=25]
resource_name = "FlashLabel"
@ -36,13 +30,6 @@ tracks/0/keys = {
[sub_resource type="AnimationNodeStateMachinePlayback" id=26]
[sub_resource type="MultiMesh" id=27]
color_format = 1
transform_format = 1
custom_data_format = 1
visible_instance_count = 0
mesh = ExtResource( 13 )
[node name="Game" type="Spatial"]
script = ExtResource( 9 )
@ -86,8 +73,8 @@ anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -141.0
margin_top = -172.0
margin_left = -67.0
margin_top = -34.0
grow_horizontal = 0
grow_vertical = 0
mouse_filter = 2
@ -97,8 +84,8 @@ size_flags_vertical = 3
[node name="DebugStatsContainer" type="GridContainer" parent="DebugContainer"]
margin_left = 7.0
margin_top = 7.0
margin_right = 134.0
margin_bottom = 165.0
margin_right = 60.0
margin_bottom = 27.0
grow_horizontal = 0
grow_vertical = 0
mouse_filter = 2
@ -295,18 +282,19 @@ margin_right = 40.0
margin_bottom = 40.0
mouse_filter = 2
[node name="WorldGeneratorContainer" type="VBoxContainer" parent="Generator Container"]
[node name="WorldGeneratorWidget" type="VBoxContainer" parent="Generator Container"]
margin_left = 10.0
margin_top = 10.0
margin_right = 145.0
margin_bottom = 94.0
script = ExtResource( 12 )
script = ExtResource( 1 )
[node name="HBoxContainer" type="HBoxContainer" parent="Generator Container/WorldGeneratorContainer"]
[node name="HBoxContainer" type="HBoxContainer" parent="Generator Container/WorldGeneratorWidget"]
visible = false
margin_right = 135.0
margin_bottom = 16.0
[node name="WorldSizeSlider" type="HSlider" parent="Generator Container/WorldGeneratorContainer/HBoxContainer"]
[node name="WorldSizeSlider" type="HSlider" parent="Generator Container/WorldGeneratorWidget/HBoxContainer"]
margin_right = 123.0
margin_bottom = 16.0
size_flags_horizontal = 3
@ -314,26 +302,25 @@ min_value = 1.0
max_value = 256.0
value = 1.0
[node name="WorldSizeLabel" type="Label" parent="Generator Container/WorldGeneratorContainer/HBoxContainer"]
[node name="WorldSizeLabel" type="Label" parent="Generator Container/WorldGeneratorWidget/HBoxContainer"]
margin_left = 127.0
margin_top = 1.0
margin_right = 135.0
margin_bottom = 15.0
text = "4"
[node name="WorldGenerateButton" type="Button" parent="Generator Container/WorldGeneratorContainer"]
margin_top = 20.0
[node name="WorldGenerateButton" type="Button" parent="Generator Container/WorldGeneratorWidget"]
visible = false
margin_right = 135.0
margin_bottom = 40.0
margin_bottom = 20.0
text = "Generate"
[node name="ShowTexturesCheckButton" type="CheckButton" parent="Generator Container/WorldGeneratorContainer"]
margin_top = 44.0
[node name="ShowTexturesCheckButton" type="CheckButton" parent="Generator Container/WorldGeneratorWidget"]
margin_right = 135.0
margin_bottom = 84.0
margin_bottom = 40.0
text = "Textures"
[node name="WorldTextureRect" type="TextureRect" parent="Generator Container/WorldGeneratorContainer"]
[node name="WorldTextureRect" type="TextureRect" parent="Generator Container/WorldGeneratorWidget"]
visible = false
margin_top = 88.0
margin_right = 135.0
@ -343,7 +330,7 @@ expand = true
stretch_mode = 5
flip_v = true
[node name="HeightTextureRect" type="TextureRect" parent="Generator Container/WorldGeneratorContainer"]
[node name="HeightTextureRect" type="TextureRect" parent="Generator Container/WorldGeneratorWidget"]
visible = false
margin_top = 88.0
margin_right = 135.0
@ -385,34 +372,7 @@ input_ray_pickable = false
[node name="Chest" parent="Entities" instance=ExtResource( 11 )]
transform = Transform( -0.825665, 0, 0.56416, 0, 1, 0, -0.56416, 0, -0.825665, -3.27709, 0, 1.02593 )
[node name="World" type="Spatial" parent="."]
script = ExtResource( 7 )
[node name="Chunks" type="Spatial" parent="World"]
[node name="TileMultiMeshInstance" type="MultiMeshInstance" parent="World"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2.5, 0 )
multimesh = SubResource( 27 )
[node name="Assets" type="Spatial" parent="World"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -5, 0 )
visible = false
[node name="Rocks" type="Spatial" parent="World/Assets"]
[node name="rockA" parent="World/Assets/Rocks" instance=ExtResource( 16 )]
[node name="rockB" parent="World/Assets/Rocks" instance=ExtResource( 18 )]
[node name="rockC" parent="World/Assets/Rocks" instance=ExtResource( 17 )]
[node name="Grass" type="Spatial" parent="World/Assets"]
[node name="grassLarge" parent="World/Assets/Grass" instance=ExtResource( 20 )]
[node name="Trees" type="Spatial" parent="World/Assets"]
[node name="tree" parent="World/Assets/Trees" instance=ExtResource( 19 )]
[node name="World" parent="." instance=ExtResource( 7 )]
[node name="DirectionalLight" type="DirectionalLight" parent="."]
transform = Transform( 0.328059, -0.878387, 0.347583, 0, 0.367946, 0.929847, -0.944657, -0.305045, 0.120708, 0, 6.59293, 1.20265 )
@ -420,8 +380,8 @@ shadow_enabled = true
directional_shadow_mode = 0
[connection signal="toggled" from="DebugContainer/DebugStatsContainer/DebugMenuButton" to="DebugContainer/DebugStatsContainer" method="_on_DebugMenuButton_toggled"]
[connection signal="value_changed" from="Generator Container/WorldGeneratorContainer/HBoxContainer/WorldSizeSlider" to="Generator Container/WorldGeneratorContainer" method="_on_HSlider_value_changed"]
[connection signal="toggled" from="Generator Container/WorldGeneratorContainer/ShowTexturesCheckButton" to="Generator Container/WorldGeneratorContainer" method="_on_ShowTexturesCheckButton_toggled"]
[connection signal="value_changed" from="Generator Container/WorldGeneratorWidget/HBoxContainer/WorldSizeSlider" to="Generator Container/WorldGeneratorWidget" method="_on_HSlider_value_changed"]
[connection signal="toggled" from="Generator Container/WorldGeneratorWidget/ShowTexturesCheckButton" to="Generator Container/WorldGeneratorWidget" method="_on_ShowTexturesCheckButton_toggled"]
[editable path="Player"]
[editable path="Player/Geometry/PirateAsset"]

View File

@ -8,7 +8,7 @@ using Priority_Queue;
public class World : Spatial {
public enum GenerationState {
Undefined,
Empty,
Heightmap,
TileType,
Objects,
@ -16,7 +16,7 @@ public class World : Spatial {
}
// constants
public const int ChunkSize = 14;
public int ChunkSize = 14;
public const int NumChunkRows = 3;
public const int NumChunkColumns = NumChunkRows;
private static readonly Color RockColor = new(0.5f, 0.5f, 0.4f);
@ -59,7 +59,7 @@ public class World : Spatial {
public HexGrid HexGrid = new();
public int Seed = 0;
public GenerationState State = GenerationState.Done;
public GenerationState State = GenerationState.Empty;
public Vector2 WorldTextureCoordinateOffset;
@ -105,9 +105,6 @@ public class World : Spatial {
_tileMultiMeshInstance = (MultiMeshInstance)FindNode("TileMultiMeshInstance");
Debug.Assert(_tileMultiMeshInstance != null);
_tileMultiMeshInstance.Multimesh.InstanceCount =
ChunkSize * ChunkSize * NumChunkColumns * NumChunkRows;
_usedTileMeshInstances = 0;
InitNoiseGenerator();
@ -127,8 +124,6 @@ public class World : Spatial {
foreach (Spatial asset in GetNode<Node>("Assets/Trees").GetChildren()) {
_treeAssets.Add(asset);
}
SetCenterPlaneCoord(Vector2.Zero);
}
public void InitNoiseGenerator() {
@ -141,6 +136,25 @@ public class World : Spatial {
_noiseGenerator.Lacunarity = 2;
}
public void Reset() {
foreach (Spatial chunkChild in Chunks.GetChildren()) {
chunkChild.QueueFree();
}
// foreach (WorldChunk chunk in _cachedWorldChunks.Values) {
// chunk.QueueFree();
// }
_cachedWorldChunks.Clear();
_addedChunkIndices.Clear();
_tileMultiMeshInstance.Multimesh.InstanceCount =
ChunkSize * ChunkSize * NumChunkColumns * NumChunkRows;
_usedTileMeshInstances = 0;
State = GenerationState.Empty;
}
public WorldChunk GetOrCreateWorldChunk(Vector2 chunkIndex, Color debugColor) {
WorldChunk chunk;
@ -167,6 +181,7 @@ public class World : Spatial {
private WorldChunk CreateWorldChunk(Vector2 chunkIndex, Color debugColor) {
WorldChunk result = (WorldChunk)_worldChunkScene.Instance();
result.SetSize(ChunkSize);
Chunks.AddChild(result);
result.Connect("TileClicked", this, nameof(OnTileClicked));
result.Connect("TileHovered", this, nameof(OnTileHovered));
@ -271,7 +286,7 @@ public class World : Spatial {
}
public void UpdateCenterChunkFromPlaneCoord(Vector2 planeCoord) {
if (State != GenerationState.Done) {
if (State != GenerationState.Done && State != GenerationState.Empty) {
GD.PrintErr("Cannot update chunk to new planeCoord " + planeCoord + ": Chunk generation not yet finished!");
return;
}
@ -285,7 +300,6 @@ public class World : Spatial {
WorldChunk currentChunk = GetOrCreateWorldChunk(CenterChunkIndex,
new Color(GD.Randf(), GD.Randf(), GD.Randf()));
_centerChunkRect = new Rect2(
new Vector2(currentChunk.Transform.origin.x, currentChunk.Transform.origin.z)
+ currentChunk.PlaneRect.Position,
@ -378,6 +392,10 @@ public class World : Spatial {
}
public void SetCenterPlaneCoord(Vector2 centerPlaneCoord) {
if (State != GenerationState.Done) {
return;
}
if (!_centerChunkRect.HasPoint(centerPlaneCoord)) {
UpdateCenterChunkFromPlaneCoord(centerPlaneCoord);
@ -450,6 +468,11 @@ public class World : Spatial {
if (nextHexCost != 0) {
Vector2 nextOffset = cell.OffsetCoords;
Vector2 chunkIndex = GetChunkIndexFromOffsetCoord(nextOffset);
if (!_cachedWorldChunks.ContainsKey(chunkIndex)) {
return 0;
}
WorldChunk chunk = _cachedWorldChunks[chunkIndex];
Vector2 textureCoordinate = nextOffset - Vector2.One * ChunkSize * chunkIndex;
@ -546,6 +569,81 @@ public class World : Spatial {
return result;
}
public bool CheckSweptTriangleCellCollision(Entity entity, Vector3 startWorld, Vector3 endWorld, float radius) {
Vector2 startPlane = new(startWorld.x, startWorld.z);
Vector2 endPlane = new(endWorld.x, endWorld.z);
Vector2 directionPlane = (endPlane - startPlane).Normalized();
Vector2 sidePlane = directionPlane.Rotated(Mathf.Pi * 0.5f);
List<HexCell> cells =
HexGrid.GetCellsForLine(startPlane + directionPlane * radius, endPlane + directionPlane * radius);
foreach (HexCell cell in cells) {
if (GetHexCost(entity, cell) == 0) {
return true;
}
}
cells = HexGrid.GetCellsForLine(startPlane + sidePlane * radius, endPlane + sidePlane * radius);
foreach (HexCell cell in cells) {
if (GetHexCost(entity, cell) == 0) {
return true;
}
}
cells = HexGrid.GetCellsForLine(startPlane - sidePlane * radius, endPlane - sidePlane * radius);
foreach (HexCell cell in cells) {
if (GetHexCost(entity, cell) == 0) {
return true;
}
}
return false;
}
public List<NavigationPoint> SmoothPath(Entity entity, List<NavigationPoint> navigationPoints) {
if (navigationPoints.Count <= 2) {
return navigationPoints;
}
Vector3 bodyGlobalTranslation = entity.GlobalTranslation;
List<NavigationPoint> smoothedPath = new();
int startIndex = 0;
int endIndex = navigationPoints.Count > 1 ? 1 : 0;
smoothedPath.Add(navigationPoints[startIndex]);
Vector3 startPoint = navigationPoints[startIndex].WorldPosition;
while (endIndex != navigationPoints.Count) {
Vector3 endPoint = navigationPoints[endIndex].WorldPosition;
if (CheckSweptTriangleCellCollision(entity, startPoint, endPoint, 0.27f)) {
if (endIndex - startIndex == 1) {
GD.Print("Aborting SmoothPath: input path passes through collision geometry.");
entity.GlobalTranslation = bodyGlobalTranslation;
return smoothedPath;
}
smoothedPath.Add(navigationPoints[endIndex - 1]);
startIndex = endIndex - 1;
startPoint = navigationPoints[startIndex].WorldPosition;
entity.GlobalTranslation = startPoint;
continue;
}
if (endIndex == navigationPoints.Count - 1) {
break;
}
endIndex += 1;
}
smoothedPath.Add(navigationPoints[endIndex]);
entity.GlobalTranslation = bodyGlobalTranslation;
return smoothedPath;
}
public override void _Process(float delta) {
GenerationState oldState = State;

50
scenes/World.tscn Normal file
View File

@ -0,0 +1,50 @@
[gd_scene load_steps=10 format=2]
[ext_resource path="res://scenes/World.cs" type="Script" id=1]
[ext_resource path="res://entities/rockA.tscn" type="PackedScene" id=2]
[ext_resource path="res://assets/Environment/HexTileMesh.tres" type="CylinderMesh" id=3]
[ext_resource path="res://entities/Tree.cs" type="Script" id=4]
[ext_resource path="res://entities/rockC.tscn" type="PackedScene" id=5]
[ext_resource path="res://assets/Environment/grassLarge.tscn" type="PackedScene" id=6]
[ext_resource path="res://entities/rockB.tscn" type="PackedScene" id=7]
[ext_resource path="res://entities/Tree.tscn" type="PackedScene" id=8]
[sub_resource type="MultiMesh" id=27]
color_format = 1
transform_format = 1
custom_data_format = 1
visible_instance_count = 0
mesh = ExtResource( 3 )
[node name="World" type="Spatial"]
script = ExtResource( 1 )
[node name="Chunks" type="Spatial" parent="."]
[node name="TileMultiMeshInstance" type="MultiMeshInstance" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2.5, 0 )
multimesh = SubResource( 27 )
[node name="Assets" type="Spatial" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -5, 0 )
visible = false
[node name="Rocks" type="Spatial" parent="Assets"]
[node name="rockA" type="StaticBody" parent="Assets/Rocks" instance=ExtResource( 2 )]
input_ray_pickable = false
[node name="rockB" type="StaticBody" parent="Assets/Rocks" instance=ExtResource( 7 )]
input_ray_pickable = false
[node name="rockC" type="StaticBody" parent="Assets/Rocks" instance=ExtResource( 5 )]
input_ray_pickable = false
[node name="Grass" type="Spatial" parent="Assets"]
[node name="grassLarge" type="Spatial" parent="Assets/Grass" groups=["GameGeometry"] instance=ExtResource( 6 )]
[node name="Trees" type="Spatial" parent="Assets"]
[node name="tree" type="StaticBody" parent="Assets/Trees" instance=ExtResource( 8 )]
script = ExtResource( 4 )

View File

@ -47,7 +47,7 @@ public class WorldChunk : Spatial {
// scene nodes
private MeshInstance PlaneRectMesh;
[Export] public int Size = 32;
public int Size = 32;
// resources
@ -56,12 +56,6 @@ public class WorldChunk : Spatial {
public int TileTypeMapFrameCount;
public Viewport TileTypeOffscreenViewport;
public WorldChunk() { }
public WorldChunk(int size) {
SetSize(size);
}
[Export]
public bool ShowTextureOverlay {
get => _showTextureOverlay;
@ -110,8 +104,6 @@ public class WorldChunk : Spatial {
Tiles = (Spatial)FindNode("Tiles");
Debug.Assert(Tiles != null);
SetSize(World.ChunkSize);
}
public void SetSize(int size) {
@ -129,7 +121,7 @@ public class WorldChunk : Spatial {
public void SetChunkIndex(Vector2 chunkIndex, HexGrid hexGrid) {
ChunkIndex = chunkIndex;
float chunkSize = World.ChunkSize;
float chunkSize = Size;
Vector2 planeCoordSouthWest = hexGrid.GetHexCenterFromOffset(chunkIndex * chunkSize);
@ -151,7 +143,7 @@ public class WorldChunk : Spatial {
_multiMeshInstance = multiMeshInstance;
_tileInstanceIndices.Clear();
int chunkSize = World.ChunkSize;
int chunkSize = Size;
foreach (Spatial node in Tiles.GetChildren()) {
node.QueueFree();
@ -163,7 +155,7 @@ public class WorldChunk : Spatial {
tile3D.Connect("TileClicked", this, nameof(OnTileClicked));
tile3D.Connect("TileHovered", this, nameof(OnTileHovered));
tile3D.Cell.OffsetCoords = new Vector2(chunkIndex * World.ChunkSize + new Vector2(i, j));
tile3D.Cell.OffsetCoords = new Vector2(chunkIndex * chunkSize + new Vector2(i, j));
_tileInstanceIndices.Add(tileInstanceIndexStart + _tileInstanceIndices.Count);
Transform tileTransform = Transform.Identity;
@ -176,6 +168,8 @@ public class WorldChunk : Spatial {
}
_multiMeshInstance.Multimesh.VisibleInstanceCount = _multiMeshInstance.Multimesh.InstanceCount;
GD.Print("Chunk: " + chunkIndex + " Last index: " + _tileInstanceIndices.Last());
}
public void ClearContent() {
@ -186,15 +180,15 @@ public class WorldChunk : Spatial {
public void UpdateTileTransforms() {
Transform chunkTransform = Transform.Identity;
Vector2 chunkOriginPlaneCoord = _hexGrid.GetHexCenterFromOffset(ChunkIndex * World.ChunkSize);
Vector2 chunkOriginPlaneCoord = _hexGrid.GetHexCenterFromOffset(ChunkIndex * Size);
chunkTransform.origin = new Vector3(chunkOriginPlaneCoord.x, 0, chunkOriginPlaneCoord.y);
Transform = chunkTransform;
Basis tileOrientation = new(Vector3.Up, 90f * Mathf.Pi / 180f);
foreach (int i in Enumerable.Range(0, _tileInstanceIndices.Count)) {
int column = i % World.ChunkSize;
int row = i / World.ChunkSize;
int column = i % Size;
int row = i / Size;
Vector2 tilePlaneCoord =
_hexGrid.GetHexCenterFromOffset(new Vector2(column, row));

View File

@ -11,7 +11,7 @@ public class NavigationTests : Spatial {
private ShaderMaterial _tileMaterial;
private EditorUI _editorUi;
private TileWorld _tileWorld;
private World _world;
private StreamContainer _streamContainer;
private Player _player;
private NavigationComponent _playerNavigationComponent;
@ -26,8 +26,8 @@ public class NavigationTests : Spatial {
_mouseHighlight = GetNode<Spatial>("MouseHighlight");
_editorUi = GetNode<EditorUI>("EditorUI");
_tileWorld = GetNode<TileWorld>("TileWorld");
_tileWorld.Connect("WorldGenerated", this, nameof(OnWorldGenerated));
_world = GetNode<World>("World");
_world.Connect("WorldGenerated", this, nameof(OnWorldGenerated));
_streamContainer = GetNode<StreamContainer>("StreamContainer");
_streamContainer.SetCenterTile(_currentTile);
@ -37,8 +37,8 @@ public class NavigationTests : Spatial {
// input handling
// _groundLayer.Connect("input_event", this, nameof(OnGroundLayerInputEvent));
_streamContainer.Connect("TileClicked", this, nameof(OnTileClicked));
_streamContainer.Connect("TileHovered", this, nameof(OnTileHovered));
_world.Connect("TileClicked", this, nameof(OnTileClicked));
_world.Connect("TileHovered", this, nameof(OnTileHovered));
CorrectEntityGridPositions();
}
@ -52,8 +52,8 @@ public class NavigationTests : Spatial {
Array entities = entitiesNode.GetChildren();
foreach (Spatial entity in entities) {
Vector2 entityPlaneCoords = new(entity.GlobalTranslation.x, entity.GlobalTranslation.z);
HexCell entityCell = _tileWorld.HexGrid.GetHexAt(entityPlaneCoords);
_tileWorld.MarkCellUnwalkable(entityCell);
HexCell entityCell = _world.HexGrid.GetHexAt(entityPlaneCoords);
_world.MarkCellUnwalkable(entityCell);
Vector2 cellPlaneCoords = _hexGrid.GetHexCenterFromOffset(entityCell.OffsetCoords);
Vector3 entityGlobalTranslation = entity.GlobalTranslation;
entityGlobalTranslation.x = cellPlaneCoords.x;
@ -66,18 +66,18 @@ public class NavigationTests : Spatial {
_streamContainer.OnWorldGenerated();
// Properly place the Player
Vector2 centerTileCoord = (Vector2.One * _tileWorld.Size / 2).Round();
Vector3 worldCenterTileCoords = _tileWorld.GetTileWorldCenterFromOffset(centerTileCoord);
worldCenterTileCoords.y = _tileWorld.GetHeightAtOffset(centerTileCoord);
Vector2 centerTileCoord = (Vector2.One * _world.Size / 2).Round();
Vector3 worldCenterTileCoords = _world.GetTileWorldCenterFromOffset(centerTileCoord);
worldCenterTileCoords.y = _world.GetHeightAtOffset(centerTileCoord);
Transform playerTransform = Transform.Identity;
playerTransform.origin = worldCenterTileCoords;
_player.Transform = playerTransform;
ImageTexture newWorldTexture = new();
newWorldTexture.CreateFromImage(_tileWorld.ColormapImage,
newWorldTexture.CreateFromImage(_world.ColormapImage,
(uint)(Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
_tileMaterial.SetShaderParam("MapAlbedoTexture", newWorldTexture);
_tileMaterial.SetShaderParam("TextureSize", (int)_tileWorld.ColormapImage.GetSize().x);
_tileMaterial.SetShaderParam("TextureSize", (int)_world.ColormapImage.GetSize().x);
CorrectEntityGridPositions();
}
@ -100,7 +100,7 @@ public class NavigationTests : Spatial {
Vector2 planeCoords = _hexGrid.GetHexCenterFromOffset(_currentTile.OffsetCoords);
Transform tileTransform = Transform.Identity;
tileTransform.origin.x = planeCoords.x;
tileTransform.origin.y = _tileWorld.GetHeightAtOffset(_currentTile.OffsetCoords) + 0.1f;
tileTransform.origin.y = _world.GetHeightAtOffset(_currentTile.OffsetCoords) + 0.1f;
tileTransform.origin.z = planeCoords.y;
_mouseHighlight.Transform = tileTransform;

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=25 format=2]
[gd_scene load_steps=26 format=2]
[ext_resource path="res://entities/Player.tscn" type="PackedScene" id=1]
[ext_resource path="res://scenes/TileWorld.tscn" type="PackedScene" id=2]
@ -11,6 +11,7 @@
[ext_resource path="res://scenes/HexTile3DPatch.tscn" type="PackedScene" id=9]
[ext_resource path="res://entities/rockB.tscn" type="PackedScene" id=10]
[ext_resource path="res://entities/Chest.tscn" type="PackedScene" id=11]
[ext_resource path="res://scenes/World.tscn" type="PackedScene" id=12]
[sub_resource type="AnimationNodeStateMachinePlayback" id=8]
@ -289,18 +290,21 @@ script = ExtResource( 4 )
[node name="Player" parent="." instance=ExtResource( 1 )]
collision_mask = 1
TileWorldNode = NodePath("../TileWorld")
WorldNode = NodePath("../World")
[node name="ToolAttachement" parent="Player/Geometry/Armature/Skeleton" index="5"]
transform = Transform( 1, 8.68458e-08, -1.04308e-07, 1.74623e-07, -1, -1.30385e-07, 1.41561e-07, 1.50874e-07, -1, -0.72, 0.45, 3.28113e-08 )
[node name="WorldInfo" parent="Player" index="2"]
WorldPath = NodePath("../../World")
[node name="ToolAttachement" parent="Player/Geometry/PirateAsset/Armature/Skeleton" index="5"]
transform = Transform( 1, 7.13626e-08, -4.47035e-08, 1.64262e-07, -1, -1.00583e-07, 1.19209e-07, 1.18278e-07, -1, -0.72, 0.45, 1.78362e-08 )
[node name="AnimationTree" parent="Player/Geometry" index="2"]
parameters/playback = SubResource( 8 )
[node name="TileWorld" parent="." instance=ExtResource( 2 )]
DebugMap = true
GenerationMapType = 2
Size = 20
DebugMap = true
[node name="MouseHighlight" parent="." instance=ExtResource( 3 )]
@ -374,8 +378,10 @@ anims/TreeShake = SubResource( 17 )
[node name="Geometry" parent="Entities/Tree5" index="2"]
transform = Transform( 1.5, 0, 0, 0, 0.984722, 0.266325, 0, -0.177712, 1.47574, 0, 0, 0 )
[node name="World" parent="." instance=ExtResource( 12 )]
[editable path="Player"]
[editable path="Player/Geometry"]
[editable path="Player/Geometry/PirateAsset"]
[editable path="TileWorld"]
[editable path="StreamContainer"]
[editable path="Entities/Chest"]

View File

@ -1,21 +1,26 @@
extends VBoxContainer
extends CenterContainer
var world_size_label = null
var world_size_slider = null
onready var SeedLineEdit: LineEdit
onready var ChunkSizeSpinBox: SpinBox
onready var GameScene: PackedScene = preload ("res://scenes/Game.tscn")
onready var WorldTextureRect = $WorldTextureRect
onready var HeightTextureRect = $HeightTextureRect
# Called when the node enters the scene tree for the first time.
func _ready():
world_size_label = find_node("WorldSizeLabel")
world_size_slider = find_node("WorldSizeSlider");
SeedLineEdit = find_node("SeedLineEdit")
assert(SeedLineEdit)
world_size_slider.value = 4
ChunkSizeSpinBox = find_node("ChunkSizeSpinBox")
assert(ChunkSizeSpinBox)
func _on_HSlider_value_changed(value):
world_size_label.text = str(value)
func _on_ShowTexturesCheckButton_toggled(button_pressed):
WorldTextureRect.visible = button_pressed
HeightTextureRect.visible = button_pressed
func _on_RefreshSeedButton_pressed():
var rng = RandomNumberGenerator.new()
rng.seed = Time.get_ticks_msec()
SeedLineEdit.text = str(rng.randi())
func _on_GenerateButton_pressed():
var game_scene_instance = GameScene.instance()
self.visible = false
get_tree().get_root().add_child(game_scene_instance)
game_scene_instance.StartNewGame(int(SeedLineEdit.text), int(ChunkSizeSpinBox.value))

121
ui/WorldGeneratorUI.tscn Normal file
View File

@ -0,0 +1,121 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://ui/WorldGeneratorUI.gd" type="Script" id=1]
[node name="WorldGeneratorUI" type="CenterContainer"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
[node name="VBoxContainer" type="VBoxContainer" parent="."]
margin_left = 16.0
margin_top = 81.0
margin_right = 303.0
margin_bottom = 319.0
custom_constants/separation = 20
[node name="Label" type="Label" parent="VBoxContainer"]
margin_right = 287.0
margin_bottom = 14.0
text = "World Generation"
align = 1
[node name="GridContainer" type="GridContainer" parent="VBoxContainer"]
margin_top = 34.0
margin_right = 287.0
margin_bottom = 198.0
columns = 3
[node name="Label" type="Label" parent="VBoxContainer/GridContainer"]
margin_top = 5.0
margin_right = 69.0
margin_bottom = 19.0
text = "Seed"
[node name="SeedLineEdit" type="LineEdit" parent="VBoxContainer/GridContainer"]
margin_left = 73.0
margin_right = 223.0
margin_bottom = 24.0
rect_min_size = Vector2( 150, 0 )
text = "0"
align = 2
caret_blink = true
[node name="RefreshSeedButton" type="Button" parent="VBoxContainer/GridContainer"]
margin_left = 227.0
margin_right = 287.0
margin_bottom = 24.0
text = "Refresh"
[node name="Label2" type="Label" parent="VBoxContainer/GridContainer"]
margin_top = 33.0
margin_right = 69.0
margin_bottom = 47.0
text = "Chunk Size"
[node name="ChunkSizeSpinBox" type="SpinBox" parent="VBoxContainer/GridContainer"]
margin_left = 73.0
margin_top = 28.0
margin_right = 223.0
margin_bottom = 52.0
min_value = 4.0
step = 2.0
value = 10.0
rounded = true
align = 2
[node name="Empty" type="Label" parent="VBoxContainer/GridContainer"]
margin_left = 227.0
margin_top = 33.0
margin_right = 287.0
margin_bottom = 47.0
[node name="Label4" type="Label" parent="VBoxContainer/GridContainer"]
margin_top = 103.0
margin_right = 69.0
margin_bottom = 117.0
text = "Objects"
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/GridContainer"]
margin_left = 73.0
margin_top = 56.0
margin_right = 223.0
margin_bottom = 164.0
[node name="ObjectTypeTreeCheckbox" type="CheckBox" parent="VBoxContainer/GridContainer/VBoxContainer"]
margin_right = 150.0
margin_bottom = 24.0
pressed = true
text = "Trees"
[node name="ObjectTypeGrassCheckbox" type="CheckBox" parent="VBoxContainer/GridContainer/VBoxContainer"]
margin_top = 28.0
margin_right = 150.0
margin_bottom = 52.0
pressed = true
text = "Grass"
[node name="ObjectTypeChestCheckbox" type="CheckBox" parent="VBoxContainer/GridContainer/VBoxContainer"]
margin_top = 56.0
margin_right = 150.0
margin_bottom = 80.0
pressed = true
text = "Chests"
[node name="ObjectTypeRockCheckbox" type="CheckBox" parent="VBoxContainer/GridContainer/VBoxContainer"]
margin_top = 84.0
margin_right = 150.0
margin_bottom = 108.0
pressed = true
text = "Rocks"
[node name="GenerateButton" type="Button" parent="VBoxContainer"]
margin_left = 216.0
margin_top = 218.0
margin_right = 287.0
margin_bottom = 238.0
size_flags_horizontal = 8
text = "Generate"
[connection signal="pressed" from="VBoxContainer/GridContainer/RefreshSeedButton" to="." method="_on_RefreshSeedButton_pressed"]
[connection signal="pressed" from="VBoxContainer/GenerateButton" to="." method="_on_GenerateButton_pressed"]

View File

@ -0,0 +1,21 @@
extends VBoxContainer
var world_size_label = null
var world_size_slider = null
onready var WorldTextureRect = $WorldTextureRect
onready var HeightTextureRect = $HeightTextureRect
# Called when the node enters the scene tree for the first time.
func _ready():
world_size_label = find_node("WorldSizeLabel")
world_size_slider = find_node("WorldSizeSlider");
world_size_slider.value = 4
func _on_HSlider_value_changed(value):
world_size_label.text = str(value)
func _on_ShowTexturesCheckButton_toggled(button_pressed):
WorldTextureRect.visible = button_pressed
HeightTextureRect.visible = button_pressed