Compare commits

...

2 Commits

Author SHA1 Message Date
Martin Felis ce53cdba6a Tree chopping only possible with axe. 2024-01-01 16:07:27 +01:00
Martin Felis b6b11228a5 Added Wood entity, trees drop 1-2 Wood logs when chopped. 2024-01-01 15:56:56 +01:00
7 changed files with 218 additions and 13 deletions

View File

@ -9,11 +9,17 @@ public class Player : Entity, IInteractionInterface {
// public members
[Export] public NodePath WorldNode;
public int WoodCount;
public int GoldCount;
public bool HasAxe = false;
public TaskQueueComponent TaskQueueComponent;
public NavigationComponent NavigationComponent { get; private set; }
public InteractionComponent InteractionComponent { get; set; }
[Signal]
private delegate void WoodCountChanged(int woodCount);
[Signal]
private delegate void GoldCountChanged(int goldCount);
@ -111,6 +117,11 @@ public class Player : Entity, IInteractionInterface {
GoldBar bar = (GoldBar)node;
bar.SetTarget(GlobalTransform.origin);
}
if (node is Wood) {
Wood wood = (Wood)node;
wood.SetTarget(GlobalTransform.origin);
}
}
UpdateDebugGeometry();
@ -139,6 +150,11 @@ public class Player : Entity, IInteractionInterface {
bar.UnsetTarget();
}
if (node is Wood) {
Wood wood = (Wood)node;
wood.UnsetTarget();
}
_attractedItemList.Remove(node);
}
@ -152,6 +168,9 @@ public class Player : Entity, IInteractionInterface {
if (body is GoldBar) {
GoldCount++;
EmitSignal("GoldCountChanged", GoldCount);
} else if (body is Wood) {
WoodCount++;
EmitSignal("WoodCountChanged", WoodCount);
}
body.QueueFree();
@ -161,8 +180,10 @@ public class Player : Entity, IInteractionInterface {
Debug.Assert(_toolAttachement != null);
if (toolName == "Axe") {
_toolAttachement.Visible = true;
HasAxe = true;
} else if (toolName == "") {
_toolAttachement.Visible = false;
HasAxe = false;
}
}
@ -175,6 +196,12 @@ public class Player : Entity, IInteractionInterface {
GD.Print("Player Opening Box");
stateMachine.Travel("Interaction");
} else if (InteractionComponent.TargetEntity is Tree) {
if (!HasAxe) {
GD.Print("Not chopping tree, player has no Axe!");
InteractionComponent.EndInteraction();
return;
}
GD.Print("Player Chopping Tree");
stateMachine.Travel("Hit");
}

View File

@ -1,10 +1,13 @@
using System;
using System.Diagnostics;
using System.Linq;
using Godot;
using GodotComponentTest.components;
using GodotComponentTest.entities;
public class Tree : StaticBody, IInteractionInterface {
private readonly PackedScene _woodScene = GD.Load<PackedScene>("res://entities/Wood.tscn");
[Export] public float ChopDuration = 2;
public bool IsMouseOver;
public InteractionComponent InteractionComponent { get; set; }
@ -13,6 +16,7 @@ public class Tree : StaticBody, IInteractionInterface {
private AnimationPlayer _animationPlayer;
private float _health = 100;
private bool _isBeingChopped;
private bool _isDead;
[Signal]
public delegate void EntityClicked(Entity entity);
@ -41,10 +45,27 @@ public class Tree : StaticBody, IInteractionInterface {
_health = Math.Max(0, _health - delta * 100 / ChopDuration);
}
if (_health == 0) {
if (!_isDead && _health == 0) {
InteractionComponent.EndInteraction();
InteractionComponent.TargetEntity = null;
GD.Print("Tree chopped!");
int numWoodLogs = (int)(GD.Randi() % 2) + 1;
foreach (int i in Enumerable.Range(1, numWoodLogs)) {
Wood wood = (Wood)_woodScene.Instance();
wood.Transform = new Transform(Transform.basis.Rotated(Vector3.Up, GD.Randf() * 2 * Mathf.Pi),
Transform.origin + Vector3.Up * 0.8f);
wood.velocity = new Vector3(
(GD.Randf() * 2f - 1f) * 1.2f,
5 + GD.Randf() * 0.3f,
(GD.Randf() * 2f - 1f) * 1.2f
);
GetParent().AddChild(wood);
}
_isDead = true;
EmitSignal("TreeChopped", this);
}
}

49
entities/Wood.cs Normal file
View File

@ -0,0 +1,49 @@
using Godot;
public class Wood : KinematicBody {
private Vector3 targetPosition;
private bool hasTarget;
public Vector3 velocity;
// Called when the node enters the scene tree for the first time.
public override void _Ready() {
targetPosition = GlobalTransform.origin;
}
public void SetTarget(Vector3 target) {
targetPosition = target;
hasTarget = true;
}
public void UnsetTarget() {
hasTarget = false;
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _PhysicsProcess(float delta) {
if (hasTarget) {
if (targetPosition.IsEqualApprox(GlobalTransform.origin)) {
targetPosition = GlobalTransform.origin;
velocity = Vector3.Zero;
}
Vector3 targetDirection = (targetPosition - GlobalTransform.origin).Normalized();
velocity = targetDirection * (velocity.Length() + 10 * delta);
Transform = new Transform(Transform.basis.Rotated(Vector3.Up, delta * 2.0f), Transform.origin);
} else {
velocity.y = velocity.y - 9.81f * delta;
}
velocity = MoveAndSlide(velocity, Vector3.Up);
if (IsOnFloor() || Mathf.Abs(Transform.origin.y) < 0.01) {
// apply damping when on ground
velocity = velocity - velocity.Normalized() * 0.9f * delta;
}
if (velocity.LengthSquared() < 0.01) {
velocity = Vector3.Zero;
}
}
}

22
entities/Wood.tscn Normal file
View File

@ -0,0 +1,22 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://entities/Wood.cs" type="Script" id=1]
[ext_resource path="res://assets/KenneySurvivalKit/Models/resourceWood.glb" type="PackedScene" id=2]
[sub_resource type="BoxShape" id=21]
extents = Vector3( 0.344943, 0.0817164, 0.173406 )
[node name="Wood" type="KinematicBody"]
collision_layer = 9
collision_mask = 0
input_ray_pickable = false
script = ExtResource( 1 )
[node name="CollisionShape" type="CollisionShape" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.084728, 0 )
shape = SubResource( 21 )
[node name="Spatial" type="Spatial" parent="."]
transform = Transform( 2.12132, 0, -2.12132, 0, 3, 0, 2.12132, 0, 2.12132, 0, 0, 0 )
[node name="resourceWood" parent="Spatial" instance=ExtResource( 2 )]

View File

@ -12,6 +12,7 @@ public class Game : Spatial {
// ui elements
private Label _framesPerSecondLabel;
private Control _gameUi;
private Label _woodCountLabel;
private Label _goldCountLabel;
private TextureRect _heightTextureRect;
@ -52,6 +53,8 @@ public class Game : Spatial {
_worldTextureRect = worldGeneratorWidget.GetNode<TextureRect>("WorldTextureRect");
_heightTextureRect = worldGeneratorWidget.GetNode<TextureRect>("HeightTextureRect");
_gameUi = (Control)FindNode("GameUI");
_woodCountLabel = _gameUi.GetNode<Label>("WoodCount");
Debug.Assert(_woodCountLabel != null);
_goldCountLabel = _gameUi.GetNode<Label>("GoldCount");
Debug.Assert(_goldCountLabel != null);
@ -83,6 +86,7 @@ public class Game : Spatial {
// connect signals
_player.TaskQueueComponent.Connect("StartInteraction", _interactionSystem,
nameof(_interactionSystem.OnStartInteraction));
_player.Connect("WoodCountChanged", this, nameof(OnWoodCountChanged));
_player.Connect("GoldCountChanged", this, nameof(OnGoldCountChanged));
_world.Connect("TileClicked", this, nameof(OnTileClicked));
_world.Connect("TileHovered", this, nameof(OnTileHovered));
@ -104,7 +108,7 @@ public class Game : Spatial {
UpdateCurrentTile();
StartNewGame(123, 12);
StartNewGame(2, 12);
}
@ -124,7 +128,7 @@ public class Game : Spatial {
_world.InitNoiseGenerator();
ResetGame();
_world.UpdateCenterChunkFromPlaneCoord(Vector2.Zero);
}
@ -233,6 +237,7 @@ public class Game : Spatial {
_player.NavigationComponent.PlanDirectPath(_player, playerStartTransform.origin, playerStartTransform.origin,
playerStartTransform.basis.Quat());
_woodCountLabel.Text = "0";
_goldCountLabel.Text = "0";
foreach (Spatial entity in GetNode("Entities").GetChildren()) {
@ -265,8 +270,16 @@ public class Game : Spatial {
_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();
}
public void OnGoldCountChanged(int goldCount) {
AnimationPlayer animationPlayer = _gameUi.GetNode<AnimationPlayer>("AnimationPlayer");
AnimationPlayer animationPlayer = _goldCountLabel.GetNode<AnimationPlayer>("AnimationPlayer");
_goldCountLabel.Text = goldCount.ToString();
animationPlayer.CurrentAnimation = "FlashLabel";
animationPlayer.Seek(0);

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=15 format=2]
[gd_scene load_steps=18 format=2]
[ext_resource path="res://ui/WorldGeneratorWidget.gd" type="Script" id=1]
[ext_resource path="res://entities/Player.tscn" type="PackedScene" id=2]
@ -9,10 +9,42 @@
[ext_resource path="res://scenes/World.tscn" type="PackedScene" id=7]
[ext_resource path="res://ui/WorldGeneratorUI.tscn" type="PackedScene" id=8]
[ext_resource path="res://scenes/Game.cs" type="Script" id=9]
[ext_resource path="res://entities/Wood.tscn" type="PackedScene" id=10]
[ext_resource path="res://entities/Chest.tscn" type="PackedScene" id=11]
[ext_resource path="res://entities/Axe.tscn" type="PackedScene" id=14]
[ext_resource path="res://systems/InteractionSystem.cs" type="Script" id=15]
[sub_resource type="Animation" id=27]
resource_name = "FlashLabel"
length = 0.3
tracks/0/type = "value"
tracks/0/path = NodePath("WoodCount:rect_scale")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.1, 0.3 ),
"transitions": PoolRealArray( 1, 0.1701, 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ), Vector2( 2, 2 ), Vector2( 1, 1 ) ]
}
[sub_resource type="Animation" id=28]
length = 0.001
tracks/0/type = "value"
tracks/0/path = NodePath("WoodCount:rect_scale")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ) ]
}
[sub_resource type="Animation" id=25]
resource_name = "FlashLabel"
length = 0.3
@ -47,25 +79,49 @@ margin_left = -40.0
margin_right = -10.0
margin_bottom = 40.0
grow_horizontal = 0
mouse_filter = 2
alignment = 2
[node name="GoldLabel" type="Label" parent="GameUI"]
[node name="WoodLabel" type="Label" parent="GameUI"]
margin_top = 13.0
margin_right = 30.0
margin_right = 37.0
margin_bottom = 27.0
text = "Gold"
text = "Wood"
[node name="GoldCount" type="Label" parent="GameUI"]
margin_left = 34.0
[node name="WoodCount" type="Label" parent="GameUI"]
margin_left = 41.0
margin_top = 13.0
margin_right = 84.0
margin_right = 91.0
margin_bottom = 27.0
rect_min_size = Vector2( 50, 0 )
rect_pivot_offset = Vector2( 45, 8 )
text = "0"
align = 2
[node name="AnimationPlayer" type="AnimationPlayer" parent="GameUI"]
[node name="AnimationPlayer" type="AnimationPlayer" parent="GameUI/WoodCount"]
root_node = NodePath("../..")
anims/FlashLabel = SubResource( 27 )
anims/RESET = SubResource( 28 )
[node name="GoldLabel" type="Label" parent="GameUI"]
margin_left = 95.0
margin_top = 13.0
margin_right = 125.0
margin_bottom = 27.0
text = "Gold"
[node name="GoldCount" type="Label" parent="GameUI"]
margin_left = 129.0
margin_top = 13.0
margin_right = 179.0
margin_bottom = 27.0
rect_min_size = Vector2( 50, 0 )
rect_pivot_offset = Vector2( 45, 8 )
text = "0"
align = 2
[node name="AnimationPlayer" type="AnimationPlayer" parent="GameUI/GoldCount"]
root_node = NodePath("../..")
anims/FlashLabel = SubResource( 25 )
[node name="DebugContainer" type="PanelContainer" parent="."]
@ -359,6 +415,9 @@ WorldNode = NodePath("../World")
[node name="WorldInfo" parent="Player" index="2"]
WorldPath = NodePath("../../World")
[node name="Skeleton" parent="Player/Geometry/PirateAsset/Armature" index="0"]
bones/4/bound_children = [ ]
[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 )
@ -374,6 +433,21 @@ 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="Wood" parent="Entities" instance=ExtResource( 10 )]
transform = Transform( 0.791533, 0, 0.611126, 0, 1, 0, -0.611126, 0, 0.791533, -2.46279, 0, -0.631194 )
[node name="Wood2" parent="Entities" instance=ExtResource( 10 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -1.66947, 0, -2.19408 )
[node name="Wood3" parent="Entities" instance=ExtResource( 10 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -1.89011, 0, 1.70148 )
[node name="Wood4" parent="Entities" instance=ExtResource( 10 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 1.85616, 0, -2.01499 )
[node name="Wood5" parent="Entities" instance=ExtResource( 10 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5591, 0, 1.55701 )
[node name="World" parent="." instance=ExtResource( 7 )]
[node name="DirectionalLight" type="DirectionalLight" parent="."]

View File

@ -763,7 +763,6 @@ public class World : Spatial {
EmitSignal("TileHovered", tile);
HexTile3D.TileTypeInfo tileTypeInfo = GetTileTypeInfoAtOffset(tile.OffsetCoords);
GD.Print("Hover on TileType " + tileTypeInfo.Name + " color: " + tileTypeInfo.Color);
}
public void OnBlockingSpatialRemoved(Spatial spatialNode) {