diff --git a/project.godot b/project.godot index 6db64d2c..6a1f45d4 100644 --- a/project.godot +++ b/project.godot @@ -69,6 +69,11 @@ Inventory={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null) ] } +Throw={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":88,"key_label":0,"unicode":120,"location":0,"echo":false,"script":null) +] +} [layer_names] diff --git a/src/inventory_menu/cursor.png.import b/src/inventory_menu/cursor.png.import index 6c12185f..f52e682d 100644 --- a/src/inventory_menu/cursor.png.import +++ b/src/inventory_menu/cursor.png.import @@ -3,25 +3,26 @@ importer="texture" type="CompressedTexture2D" uid="uid://dr8mjn3wahdvp" -path="res://.godot/imported/cursor.png-0fec02edb5cdc5cc9912cb19d5a7e260.ctex" +path.s3tc="res://.godot/imported/cursor.png-0fec02edb5cdc5cc9912cb19d5a7e260.s3tc.ctex" metadata={ -"vram_texture": false +"imported_formats": ["s3tc_bptc"], +"vram_texture": true } [deps] source_file="res://src/inventory_menu/cursor.png" -dest_files=["res://.godot/imported/cursor.png-0fec02edb5cdc5cc9912cb19d5a7e260.ctex"] +dest_files=["res://.godot/imported/cursor.png-0fec02edb5cdc5cc9912cb19d5a7e260.s3tc.ctex"] [params] -compress/mode=0 +compress/mode=2 compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 -mipmaps/generate=false +mipmaps/generate=true mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" @@ -31,4 +32,4 @@ process/normal_map_invert_y=false process/hdr_as_srgb=false process/hdr_clamp_exposure=false process/size_limit=0 -detect_3d/compress_to=1 +detect_3d/compress_to=0 diff --git a/src/items/throwable/ThrowableItem.cs b/src/items/throwable/ThrowableItem.cs new file mode 100644 index 00000000..deb903df --- /dev/null +++ b/src/items/throwable/ThrowableItem.cs @@ -0,0 +1,30 @@ +using Chickensoft.AutoInject; +using Chickensoft.GodotNodeInterfaces; +using Chickensoft.Introspection; +using Godot; + +public interface IThrowableItem : INode3D +{ + public IAnimationPlayer AnimationPlayer { get; set; } +} + +[Meta(typeof(IAutoNode))] +public partial class ThrowableItem : Node3D, IThrowableItem +{ + public override void _Notification(int what) => this.Notify(what); + + [Node] public IAnimationPlayer AnimationPlayer { get; set; } = default!; + + [Node] public IHitbox Hitbox { get; set; } = default!; + + public void Setup() + { + AnimationPlayer.AnimationFinished += OnAnimationFinished; + Hitbox.Damage = 5; + } + + private void OnAnimationFinished(StringName animName) + { + QueueFree(); + } +} diff --git a/src/items/throwable/ThrowableItem.tscn b/src/items/throwable/ThrowableItem.tscn new file mode 100644 index 00000000..ef8c59d5 --- /dev/null +++ b/src/items/throwable/ThrowableItem.tscn @@ -0,0 +1,69 @@ +[gd_scene load_steps=8 format=3 uid="uid://1fl6s352e2ej"] + +[ext_resource type="Script" path="res://src/items/throwable/ThrowableItem.cs" id="1_nac2l"] +[ext_resource type="Texture2D" uid="uid://dr8mjn3wahdvp" path="res://src/inventory_menu/cursor.png" id="2_mojlk"] +[ext_resource type="Script" path="res://src/hitbox/Hitbox.cs" id="3_qpunu"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_qihtb"] +size = Vector3(0.371643, 0.289612, 0.286743) + +[sub_resource type="Animation" id="Animation_7gvmx"] +resource_name = "throw" +length = 2.0 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Hitbox:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 1, 0), Vector3(0, 1, -15)] +} + +[sub_resource type="Animation" id="Animation_d22ed"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Hitbox:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_qfght"] +_data = { +"RESET": SubResource("Animation_d22ed"), +"throw": SubResource("Animation_7gvmx") +} + +[node name="ThrowableItem" type="Node3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.535839) +script = ExtResource("1_nac2l") + +[node name="Hitbox" type="Area3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +collision_layer = 16 +collision_mask = 16 +script = ExtResource("3_qpunu") + +[node name="Sprite3D" type="Sprite3D" parent="Hitbox"] +billboard = 2 +texture = ExtResource("2_mojlk") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Hitbox"] +shape = SubResource("BoxShape3D_qihtb") + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +unique_name_in_owner = true +libraries = { +"": SubResource("AnimationLibrary_qfght") +} diff --git a/src/player/Player.cs b/src/player/Player.cs index f7b390c4..0fa83e8d 100644 --- a/src/player/Player.cs +++ b/src/player/Player.cs @@ -98,6 +98,10 @@ namespace GameJamDungeon .Handle((in PlayerLogic.Output.Animations.Attack output) => { AnimationPlayer.Play("attack"); + }) + .Handle((in PlayerLogic.Output.ThrowItem output) => + { + ThrowItem(); }); this.Provide(); @@ -137,6 +141,16 @@ namespace GameJamDungeon return input with { Y = 0f }; } + public void ThrowItem() + { + var itemScene = GD.Load("res://src/items/throwable/ThrowableItem.tscn"); + var throwItem = itemScene.Instantiate(); + GetTree().Root.AddChildEx(throwItem); + throwItem.GlobalPosition = GameRepo.PlayerGlobalPosition.Value; + throwItem.GlobalRotation = GlobalRotation; + throwItem.AnimationPlayer.Play("throw"); + } + public void OnAnimationFinished(StringName animation) { GD.Print("Attack finished"); diff --git a/src/player/state/PlayerLogic.Output.cs b/src/player/state/PlayerLogic.Output.cs index 5c561c51..ef955782 100644 --- a/src/player/state/PlayerLogic.Output.cs +++ b/src/player/state/PlayerLogic.Output.cs @@ -12,6 +12,8 @@ namespace GameJamDungeon } public readonly record struct MovementComputed(Basis Rotation, Vector3 Velocity); + + public readonly record struct ThrowItem; } } } diff --git a/src/player/state/states/PlayerLogic.State.Alive.cs b/src/player/state/states/PlayerLogic.State.Alive.cs index 7739e0e3..7cf0a732 100644 --- a/src/player/state/states/PlayerLogic.State.Alive.cs +++ b/src/player/state/states/PlayerLogic.State.Alive.cs @@ -24,6 +24,9 @@ namespace GameJamDungeon if (Godot.Input.IsActionPressed(GameInputs.Sprint)) velocity *= 3; + if (Godot.Input.IsActionJustPressed(GameInputs.Throw)) + Output(new Output.ThrowItem()); + Output(new Output.MovementComputed(transform.Basis, velocity)); return ToSelf();