Knockback tag implementation
This commit is contained in:
@@ -6,7 +6,7 @@ using Godot;
|
|||||||
|
|
||||||
namespace GameJamDungeon;
|
namespace GameJamDungeon;
|
||||||
|
|
||||||
public interface IEnemy : ICharacterBody3D
|
public interface IEnemy : IRigidBody3D
|
||||||
{
|
{
|
||||||
public IEnemyLogic EnemyLogic { get; }
|
public IEnemyLogic EnemyLogic { get; }
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ public interface IEnemy : ICharacterBody3D
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Meta(typeof(IAutoNode))]
|
[Meta(typeof(IAutoNode))]
|
||||||
public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
public partial class Enemy : RigidBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||||
{
|
{
|
||||||
public override void _Notification(int what) => this.Notify(what);
|
public override void _Notification(int what) => this.Notify(what);
|
||||||
|
|
||||||
@@ -69,6 +69,9 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
|||||||
|
|
||||||
private const string ATTACK_FORWARD = "attack";
|
private const string ATTACK_FORWARD = "attack";
|
||||||
|
|
||||||
|
private float _knockbackStrength = 0.0f;
|
||||||
|
private Vector3 _knockbackDirection = Vector3.Zero;
|
||||||
|
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
EnemyLogic = new EnemyLogic();
|
EnemyLogic = new EnemyLogic();
|
||||||
@@ -128,7 +131,8 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
|||||||
.Handle((in EnemyLogic.Output.MovementComputed output) =>
|
.Handle((in EnemyLogic.Output.MovementComputed output) =>
|
||||||
{
|
{
|
||||||
RotateEnemy(-GameRepo.PlayerGlobalTransform.Value.Basis.Z);
|
RotateEnemy(-GameRepo.PlayerGlobalTransform.Value.Basis.Z);
|
||||||
MoveAndSlide();
|
_knockbackStrength = _knockbackStrength * 0.9f;
|
||||||
|
MoveAndCollide(output.LinearVelocity + (_knockbackDirection * _knockbackStrength));
|
||||||
})
|
})
|
||||||
.Handle((in EnemyLogic.Output.HitByPlayer output) =>
|
.Handle((in EnemyLogic.Output.HitByPlayer output) =>
|
||||||
{
|
{
|
||||||
@@ -138,6 +142,11 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
|||||||
// TODO: Make this an event to notify game that player hit someone
|
// TODO: Make this an event to notify game that player hit someone
|
||||||
if (GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.WeaponTags.Contains(WeaponTag.SelfDamage))
|
if (GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.WeaponTags.Contains(WeaponTag.SelfDamage))
|
||||||
GameRepo.PlayerData.SetCurrentHP(GameRepo.PlayerData.CurrentHP.Value - 5);
|
GameRepo.PlayerData.SetCurrentHP(GameRepo.PlayerData.CurrentHP.Value - 5);
|
||||||
|
if (GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.WeaponTags.Contains(WeaponTag.Knockback))
|
||||||
|
{
|
||||||
|
_knockbackDirection = -GameRepo.PlayerGlobalTransform.Value.Basis.Z.Normalized();
|
||||||
|
_knockbackStrength = 0.3f;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.Handle((in EnemyLogic.Output.Attack _) =>
|
.Handle((in EnemyLogic.Output.Attack _) =>
|
||||||
{
|
{
|
||||||
@@ -265,9 +274,9 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
|||||||
AnimationTree.Get("parameters/playback").As<AnimationNodeStateMachinePlayback>().Travel("idle_back_walk");
|
AnimationTree.Get("parameters/playback").As<AnimationNodeStateMachinePlayback>().Travel("idle_back_walk");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If the dot product of the perpendicular dot product is positive (up to 1), the enemy is facing to the left (since it's mirrored).
|
// If the dot product of the perpendicular direction is positive (up to 1), the enemy is facing to the left (since it's mirrored).
|
||||||
AnimatedSprite.FlipH = leftDotProduct > 0;
|
AnimatedSprite.FlipH = leftDotProduct > 0;
|
||||||
// Check is side facing. If the dot product is close to zero in the positive or negative direction, its close to the threshold for turning.
|
// Check if side facing. If the dot product is close to zero in the positive or negative direction, its close to the threshold for turning.
|
||||||
if (Mathf.Abs(forwardDotProduct) < rotateLowerThreshold)
|
if (Mathf.Abs(forwardDotProduct) < rotateLowerThreshold)
|
||||||
AnimationTree.Get("parameters/playback").As<AnimationNodeStateMachinePlayback>().Travel("idle_left_walk");
|
AnimationTree.Get("parameters/playback").As<AnimationNodeStateMachinePlayback>().Travel("idle_left_walk");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -576,7 +576,7 @@ states/idle_left_walk/position = Vector2(331, 196.947)
|
|||||||
transitions = ["Start", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_vljb2"), "idle_front_walk", "idle_left_walk", SubResource("AnimationNodeStateMachineTransition_3xv6a"), "idle_left_walk", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_0h1op"), "idle_front_walk", "idle_back_walk", SubResource("AnimationNodeStateMachineTransition_361b7"), "idle_back_walk", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_wftla"), "idle_back_walk", "idle_left_walk", SubResource("AnimationNodeStateMachineTransition_gqqkl"), "idle_left_walk", "idle_back_walk", SubResource("AnimationNodeStateMachineTransition_5cj36"), "idle_front_walk", "attack", SubResource("AnimationNodeStateMachineTransition_4t05h"), "attack", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_8hgxu"), "attack", "idle_back_walk", SubResource("AnimationNodeStateMachineTransition_fq2yw"), "attack", "idle_left_walk", SubResource("AnimationNodeStateMachineTransition_yqm0k"), "idle_back_walk", "attack", SubResource("AnimationNodeStateMachineTransition_bmy1k"), "idle_left_walk", "attack", SubResource("AnimationNodeStateMachineTransition_mxl7w")]
|
transitions = ["Start", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_vljb2"), "idle_front_walk", "idle_left_walk", SubResource("AnimationNodeStateMachineTransition_3xv6a"), "idle_left_walk", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_0h1op"), "idle_front_walk", "idle_back_walk", SubResource("AnimationNodeStateMachineTransition_361b7"), "idle_back_walk", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_wftla"), "idle_back_walk", "idle_left_walk", SubResource("AnimationNodeStateMachineTransition_gqqkl"), "idle_left_walk", "idle_back_walk", SubResource("AnimationNodeStateMachineTransition_5cj36"), "idle_front_walk", "attack", SubResource("AnimationNodeStateMachineTransition_4t05h"), "attack", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_8hgxu"), "attack", "idle_back_walk", SubResource("AnimationNodeStateMachineTransition_fq2yw"), "attack", "idle_left_walk", SubResource("AnimationNodeStateMachineTransition_yqm0k"), "idle_back_walk", "attack", SubResource("AnimationNodeStateMachineTransition_bmy1k"), "idle_left_walk", "attack", SubResource("AnimationNodeStateMachineTransition_mxl7w")]
|
||||||
graph_offset = Vector2(-190, -62.0526)
|
graph_offset = Vector2(-190, -62.0526)
|
||||||
|
|
||||||
[node name="Michael" type="CharacterBody3D"]
|
[node name="Michael" type="RigidBody3D"]
|
||||||
process_mode = 1
|
process_mode = 1
|
||||||
collision_layer = 10
|
collision_layer = 10
|
||||||
collision_mask = 11
|
collision_mask = 11
|
||||||
|
|||||||
@@ -524,12 +524,14 @@ states/idle_left_walk/position = Vector2(331, 196.947)
|
|||||||
transitions = ["Start", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_vljb2"), "idle_front_walk", "idle_left_walk", SubResource("AnimationNodeStateMachineTransition_3xv6a"), "idle_left_walk", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_0h1op"), "idle_front_walk", "idle_back_walk", SubResource("AnimationNodeStateMachineTransition_361b7"), "idle_back_walk", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_wftla"), "idle_back_walk", "idle_left_walk", SubResource("AnimationNodeStateMachineTransition_gqqkl"), "idle_left_walk", "idle_back_walk", SubResource("AnimationNodeStateMachineTransition_5cj36"), "idle_front_walk", "attack", SubResource("AnimationNodeStateMachineTransition_4t05h"), "attack", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_8hgxu"), "attack", "idle_back_walk", SubResource("AnimationNodeStateMachineTransition_fq2yw"), "attack", "idle_left_walk", SubResource("AnimationNodeStateMachineTransition_yqm0k"), "idle_back_walk", "attack", SubResource("AnimationNodeStateMachineTransition_bmy1k"), "idle_left_walk", "attack", SubResource("AnimationNodeStateMachineTransition_mxl7w")]
|
transitions = ["Start", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_vljb2"), "idle_front_walk", "idle_left_walk", SubResource("AnimationNodeStateMachineTransition_3xv6a"), "idle_left_walk", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_0h1op"), "idle_front_walk", "idle_back_walk", SubResource("AnimationNodeStateMachineTransition_361b7"), "idle_back_walk", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_wftla"), "idle_back_walk", "idle_left_walk", SubResource("AnimationNodeStateMachineTransition_gqqkl"), "idle_left_walk", "idle_back_walk", SubResource("AnimationNodeStateMachineTransition_5cj36"), "idle_front_walk", "attack", SubResource("AnimationNodeStateMachineTransition_4t05h"), "attack", "idle_front_walk", SubResource("AnimationNodeStateMachineTransition_8hgxu"), "attack", "idle_back_walk", SubResource("AnimationNodeStateMachineTransition_fq2yw"), "attack", "idle_left_walk", SubResource("AnimationNodeStateMachineTransition_yqm0k"), "idle_back_walk", "attack", SubResource("AnimationNodeStateMachineTransition_bmy1k"), "idle_left_walk", "attack", SubResource("AnimationNodeStateMachineTransition_mxl7w")]
|
||||||
graph_offset = Vector2(-190, -62.0526)
|
graph_offset = Vector2(-190, -62.0526)
|
||||||
|
|
||||||
[node name="Sproingy" type="CharacterBody3D"]
|
[node name="Sproingy" type="RigidBody3D"]
|
||||||
process_mode = 1
|
process_mode = 1
|
||||||
collision_layer = 10
|
collision_layer = 10
|
||||||
collision_mask = 11
|
collision_mask = 11
|
||||||
axis_lock_linear_y = true
|
axis_lock_linear_y = true
|
||||||
axis_lock_angular_x = true
|
axis_lock_angular_x = true
|
||||||
|
contact_monitor = true
|
||||||
|
max_contacts_reported = 1
|
||||||
script = ExtResource("1_7tinp")
|
script = ExtResource("1_7tinp")
|
||||||
EnemyStatResource = SubResource("Resource_rxw8v")
|
EnemyStatResource = SubResource("Resource_rxw8v")
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace GameJamDungeon
|
|||||||
{
|
{
|
||||||
public readonly record struct MoveTowardsPlayer(Vector3 TargetPosition);
|
public readonly record struct MoveTowardsPlayer(Vector3 TargetPosition);
|
||||||
|
|
||||||
public readonly record struct MovementComputed();
|
public readonly record struct MovementComputed(Vector3 LinearVelocity);
|
||||||
|
|
||||||
public readonly record struct HitByPlayer(double CurrentHP);
|
public readonly record struct HitByPlayer(double CurrentHP);
|
||||||
|
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ namespace GameJamDungeon
|
|||||||
enemy.NavAgent.TargetPosition = target;
|
enemy.NavAgent.TargetPosition = target;
|
||||||
var targetPosition = enemy.NavAgent.GetNextPathPosition();
|
var targetPosition = enemy.NavAgent.GetNextPathPosition();
|
||||||
|
|
||||||
enemy.Velocity = (targetPosition - enemy.GlobalTransform.Origin).Normalized() * 2f;
|
var velocity = (targetPosition - enemy.GlobalTransform.Origin).Normalized() * 2f * (float)delta;
|
||||||
var lookAtDir = enemy.GlobalTransform.Origin - enemy.Velocity;
|
var lookAtDir = enemy.GlobalTransform.Origin - velocity;
|
||||||
var lookAtPosition = new Vector3(lookAtDir.X, enemy.GlobalPosition.Y, lookAtDir.Z);
|
var lookAtPosition = new Vector3(lookAtDir.X, enemy.GlobalPosition.Y, lookAtDir.Z);
|
||||||
if (!enemy.Velocity.IsEqualApprox(Vector3.Zero) && !enemy.GlobalPosition.IsEqualApprox(lookAtPosition))
|
if (!velocity.IsEqualApprox(Vector3.Zero) && !enemy.GlobalPosition.IsEqualApprox(lookAtPosition))
|
||||||
enemy.LookAt(lookAtPosition);
|
enemy.LookAt(lookAtPosition);
|
||||||
|
|
||||||
Output(new Output.MovementComputed());
|
Output(new Output.MovementComputed(velocity));
|
||||||
return ToSelf();
|
return ToSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,15 +20,14 @@ public partial class EnemyLogic
|
|||||||
var delta = input.Delta;
|
var delta = input.Delta;
|
||||||
var enemy = Get<IEnemy>();
|
var enemy = Get<IEnemy>();
|
||||||
var targetPosition = enemy.NavAgent.GetNextPathPosition();
|
var targetPosition = enemy.NavAgent.GetNextPathPosition();
|
||||||
var velocity = (targetPosition - enemy.GlobalPosition).Normalized() * 1.0f;
|
var velocity = (targetPosition - enemy.GlobalPosition).Normalized() * 1.0f * (float)delta;
|
||||||
enemy.Velocity = velocity;
|
var lookAtDir = enemy.GlobalTransform.Origin - velocity;
|
||||||
var lookAtDir = enemy.GlobalTransform.Origin - enemy.Velocity;
|
|
||||||
|
|
||||||
var lookAtPosition = new Vector3(lookAtDir.X, enemy.GlobalPosition.Y, lookAtDir.Z);
|
var lookAtPosition = new Vector3(lookAtDir.X, enemy.GlobalPosition.Y, lookAtDir.Z);
|
||||||
if (!enemy.Velocity.IsEqualApprox(Vector3.Zero) && !enemy.GlobalPosition.IsEqualApprox(lookAtPosition))
|
if (!velocity.IsEqualApprox(Vector3.Zero) && !enemy.GlobalPosition.IsEqualApprox(lookAtPosition))
|
||||||
enemy.LookAt(new Vector3(lookAtDir.X, enemy.GlobalPosition.Y, lookAtDir.Z));
|
enemy.LookAt(new Vector3(lookAtDir.X, enemy.GlobalPosition.Y, lookAtDir.Z));
|
||||||
|
|
||||||
Output(new Output.MovementComputed());
|
Output(new Output.MovementComputed(velocity));
|
||||||
return ToSelf();
|
return ToSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
shader_type canvas_item;
|
|
||||||
|
|
||||||
float random(vec2 uv) {
|
|
||||||
return fract(sin(dot(uv, vec2(12.9898, 78.233))) * 438.5453);
|
|
||||||
}
|
|
||||||
|
|
||||||
uniform float sensitivity : hint_range(0.0, 1.0) = .5;
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
// Get size of texture in pixels
|
|
||||||
float size_x = float(textureSize(TEXTURE, 0).x);
|
|
||||||
float size_y = float(textureSize(TEXTURE, 0).y);
|
|
||||||
//
|
|
||||||
vec4 pixelColor = texture(TEXTURE, UV);
|
|
||||||
// Create a new "UV" which remaps every UV value to a snapped pixel value
|
|
||||||
vec2 UVr = vec2(floor(UV.x*size_x)/size_x, floor(UV.y*size_y)/size_y);
|
|
||||||
// Determine whether pixel should be visible or not
|
|
||||||
float visible = step(sensitivity, random(UVr));
|
|
||||||
// Draw the pixel, or not depending on if it is visible or not
|
|
||||||
COLOR = vec4(pixelColor.r, pixelColor.g, pixelColor.b, min(visible, pixelColor.a));
|
|
||||||
}
|
|
||||||
@@ -34,7 +34,7 @@ public partial class ThrowableItem : Node3D, IInventoryItem
|
|||||||
|
|
||||||
public void Throw(ThrowableItemStats throwableItemStats)
|
public void Throw(ThrowableItemStats throwableItemStats)
|
||||||
{
|
{
|
||||||
var throwableScene = GD.Load<PackedScene>("res://src/items/throwable/ThrownItem.tscn");
|
var throwableScene = GD.Load<PackedScene>("res://src/items/thrown/ThrownGeometricDice.tscn");
|
||||||
var throwable = throwableScene.Instantiate<ThrownItem>();
|
var throwable = throwableScene.Instantiate<ThrownItem>();
|
||||||
Game.AddChild(throwable);
|
Game.AddChild(throwable);
|
||||||
throwable.Throw(throwableItemStats);
|
throwable.Throw(throwableItemStats);
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
[gd_scene load_steps=7 format=3 uid="uid://b1twcuneob5kt"]
|
[gd_scene load_steps=5 format=3 uid="uid://b1twcuneob5kt"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://src/items/throwable/ThrownItem.cs" id="1_l0mpw"]
|
[ext_resource type="Script" path="res://src/items/thrown/ThrownItem.cs" id="1_ig3yn"]
|
||||||
[ext_resource type="Shader" path="res://src/items/throwable/Dissolve.gdshader" id="2_lukp6"]
|
[ext_resource type="Texture2D" uid="uid://mi70lolgtf3n" path="res://src/items/throwable/textures/GEOMANCER-DICE.png" id="2_ia1qk"]
|
||||||
[ext_resource type="Texture2D" uid="uid://mi70lolgtf3n" path="res://src/items/throwable/textures/GEOMANCER-DICE.png" id="2_oyhi4"]
|
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_s4ym5"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_s4ym5"]
|
||||||
size = Vector3(0.288967, 0.302734, 0.28064)
|
size = Vector3(0.288967, 0.302734, 0.28064)
|
||||||
@@ -10,10 +9,6 @@ size = Vector3(0.288967, 0.302734, 0.28064)
|
|||||||
[sub_resource type="ViewportTexture" id="ViewportTexture_vebu3"]
|
[sub_resource type="ViewportTexture" id="ViewportTexture_vebu3"]
|
||||||
viewport_path = NodePath("Sprite3D/SubViewport")
|
viewport_path = NodePath("Sprite3D/SubViewport")
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_vnlpn"]
|
|
||||||
shader = ExtResource("2_lukp6")
|
|
||||||
shader_parameter/sensitivity = 0.0
|
|
||||||
|
|
||||||
[node name="Hitbox" type="RigidBody3D"]
|
[node name="Hitbox" type="RigidBody3D"]
|
||||||
collision_layer = 17
|
collision_layer = 17
|
||||||
collision_mask = 16
|
collision_mask = 16
|
||||||
@@ -21,7 +16,7 @@ mass = 0.001
|
|||||||
gravity_scale = 0.0
|
gravity_scale = 0.0
|
||||||
contact_monitor = true
|
contact_monitor = true
|
||||||
max_contacts_reported = 1
|
max_contacts_reported = 1
|
||||||
script = ExtResource("1_l0mpw")
|
script = ExtResource("1_ig3yn")
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00739601, 0.0986328, 0.137878)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00739601, 0.0986328, 0.137878)
|
||||||
@@ -41,8 +36,7 @@ size = Vector2i(100, 100)
|
|||||||
[node name="Sprite" type="Sprite2D" parent="Sprite3D/SubViewport"]
|
[node name="Sprite" type="Sprite2D" parent="Sprite3D/SubViewport"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
z_index = 100
|
z_index = 100
|
||||||
material = SubResource("ShaderMaterial_vnlpn")
|
|
||||||
scale = Vector2(0.1, 0.1)
|
scale = Vector2(0.1, 0.1)
|
||||||
texture = ExtResource("2_oyhi4")
|
texture = ExtResource("2_ia1qk")
|
||||||
centered = false
|
centered = false
|
||||||
flip_h = true
|
flip_h = true
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using Chickensoft.AutoInject;
|
using Chickensoft.AutoInject;
|
||||||
using Chickensoft.GodotNodeInterfaces;
|
|
||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using GameJamDungeon;
|
using GameJamDungeon;
|
||||||
using Godot;
|
using Godot;
|
||||||
@@ -30,3 +30,4 @@ corridor_room_scene = ExtResource("4_gni6i")
|
|||||||
dungeon_size = Vector3i(50, 1, 50)
|
dungeon_size = Vector3i(50, 1, 50)
|
||||||
voxel_scale = Vector3(4, 4, 4)
|
voxel_scale = Vector3(4, 4, 4)
|
||||||
generate_on_ready = false
|
generate_on_ready = false
|
||||||
|
place_even_if_fail = true
|
||||||
|
|||||||
Reference in New Issue
Block a user