diff --git a/assets/weapons/knive.ase b/assets/weapons/knive.ase new file mode 100644 index 0000000..7d602fa Binary files /dev/null and b/assets/weapons/knive.ase differ diff --git a/assets/weapons/knvie.png b/assets/weapons/knvie.png new file mode 100644 index 0000000..ca2babf Binary files /dev/null and b/assets/weapons/knvie.png differ diff --git a/assets/weapons/knvie.png.import b/assets/weapons/knvie.png.import new file mode 100644 index 0000000..0b8ebf7 --- /dev/null +++ b/assets/weapons/knvie.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://pot4k8a6lxd0" +path="res://.godot/imported/knvie.png-6e2c57d6850f97653fad709f2c5186b5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/weapons/knvie.png" +dest_files=["res://.godot/imported/knvie.png-6e2c57d6850f97653fad709f2c5186b5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +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 diff --git a/scenes/throwing_knive.tscn b/scenes/throwing_knive.tscn new file mode 100644 index 0000000..86f1197 --- /dev/null +++ b/scenes/throwing_knive.tscn @@ -0,0 +1,33 @@ +[gd_scene format=3 uid="uid://oegpflgwf17e"] + +[ext_resource type="Script" uid="uid://dpj26ryawjq02" path="res://scripts/throwing_knive.gd" id="2_knive"] +[ext_resource type="Texture2D" uid="uid://pot4k8a6lxd0" path="res://assets/weapons/knvie.png" id="2_tyd64"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_frs86"] +atlas = ExtResource("2_tyd64") +region = Rect2(0, 0, 32, 32) + +[sub_resource type="SpriteFrames" id="SpriteFrames_t4gbw"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_frs86") +}], +"loop": true, +"name": &"default", +"speed": 5.0 +}] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_1ss1s"] +size = Vector2(15, 7) + +[node name="ThrowingKnive" type="Area2D" unique_id=882877238] +script = ExtResource("2_knive") + +[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." unique_id=164559800] +texture_filter = 1 +sprite_frames = SubResource("SpriteFrames_t4gbw") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=886320879] +position = Vector2(0.5, -0.5) +shape = SubResource("RectangleShape2D_1ss1s") diff --git a/scripts/perk_effects.gd b/scripts/perk_effects.gd index ce9005d..9c37670 100644 --- a/scripts/perk_effects.gd +++ b/scripts/perk_effects.gd @@ -3,10 +3,13 @@ extends Node2D @onready var witch = get_node("/root/Game/Witch") @onready var player = get_node("/root/Game/Player") var fireball = preload("res://scenes/fireball.tscn") +var throwing_knife = preload("res://scenes/throwing_knive.tscn") var cauldron var available_perks: Array[Perk] = [] var fireball_aoe_enabled = false -# Called when the node enters the scene tree for the first time. +var throwing_knife_enabled = false +var throwing_knife_cooldown: float = 2.0 +var _knife_timer: float = 0.0 func _ready() -> void: cauldron = witch.get_node("CauldronBar") @@ -25,20 +28,47 @@ func _ready() -> void: bexp.description = "The Witch casts an explosion on finishing a brew" bexp.effect = brew_explosion available_perks.append(bexp) - - pass # Replace with function body. + var tk = Perk.new() + tk.name = "Throwing Knife" + tk.description = "Automatically throw a knife at the nearest enemy every second" + tk.effect = enable_throwing_knife + available_perks.append(tk) - -# Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta: float) -> void: - pass + if throwing_knife_enabled: + _knife_timer += delta + if _knife_timer >= throwing_knife_cooldown: + _knife_timer = 0.0 + _shoot_throwing_knife() func double_shuriken(): witch.shuriken_count = 2 - + func fireball_aoe(): fireball_aoe_enabled = true - + func brew_explosion(): cauldron.brew_explosion = true + +func enable_throwing_knife(): + throwing_knife_enabled = true + var upg = Perk.new() + upg.name = "Knife Cooldown" + upg.description = "Reduce throwing knife cooldown by 0.2s (min 1s)" + upg.effect = knife_cooldown_upgrade + available_perks.append(upg) + +func knife_cooldown_upgrade(): + throwing_knife_cooldown = maxf(1.0, throwing_knife_cooldown - 0.2) + if throwing_knife_cooldown > 1.0: + var upg = Perk.new() + upg.name = "Knife Cooldown" + upg.description = "Reduce throwing knife cooldown by 0.2s (min 1s)" + upg.effect = knife_cooldown_upgrade + available_perks.append(upg) + +func _shoot_throwing_knife() -> void: + var knife = throwing_knife.instantiate() + knife.global_position = witch.global_position + witch.get_parent().add_child(knife) diff --git a/scripts/throwing_knive.gd b/scripts/throwing_knive.gd new file mode 100644 index 0000000..f7029be --- /dev/null +++ b/scripts/throwing_knive.gd @@ -0,0 +1,24 @@ +extends ProjectileBase + +var _target_enemy: Node = null + +func _ready() -> void: + super() + speed = 400.0 + var witch = get_node("/root/Game/Witch") + _target_enemy = witch.get_nearest_enemy(witch.global_position, _knife_filter) + if _target_enemy == null: + queue_free() + return + _target_enemy.add_to_group("knife_targeted") + tree_exiting.connect(_on_knife_exiting) + var dir = global_position.direction_to(_target_enemy.global_position) + rotation = dir.angle() + launch(_target_enemy.global_position) + +func _knife_filter(enemy: Node) -> bool: + return not enemy.is_dying and not enemy.is_hurt and not enemy.is_in_group("knife_targeted") + +func _on_knife_exiting() -> void: + if is_instance_valid(_target_enemy) and _target_enemy.is_in_group("knife_targeted"): + _target_enemy.remove_from_group("knife_targeted") diff --git a/scripts/throwing_knive.gd.uid b/scripts/throwing_knive.gd.uid new file mode 100644 index 0000000..702c511 --- /dev/null +++ b/scripts/throwing_knive.gd.uid @@ -0,0 +1 @@ +uid://dpj26ryawjq02 diff --git a/scripts/witch.gd b/scripts/witch.gd index 8366fb4..f792f42 100644 --- a/scripts/witch.gd +++ b/scripts/witch.gd @@ -43,10 +43,12 @@ func shoot_shuriken(): get_parent().add_child(sh) await get_tree().create_timer(0.2).timeout -func get_nearest_enemy(from: Vector2) -> Node: +func get_nearest_enemy(from: Vector2, filter: Callable = Callable()) -> Node: var nearest = null var min_distance = INF for enemy in get_tree().get_nodes_in_group("enemies"): + if filter.is_valid() and not filter.call(enemy): + continue var dist = from.distance_to(enemy.global_position) if dist < min_distance: min_distance = dist