From ebd9ccad8cb4cf33ac8de4b51474246fc045eea3 Mon Sep 17 00:00:00 2001 From: SondreElg Date: Sun, 5 Oct 2025 13:21:32 +0200 Subject: [PATCH] damage on cursor bullet --- growth/CardInjects/CursorGun/cursor_bullet.gd | 17 +++-- .../CardInjects/CursorGun/cursor_bullet.tscn | 3 + .../CursorGun/cursor_gun_card_inject.gd | 7 +- growth/CardInjects/Firewall/firewall.tscn | 9 ++- .../CardInjects/Katana/katana_card_inject.gd | 4 +- growth/CardInjects/Mine/mine.tscn | 1 - growth/hand.gd | 1 - growth/player.gd | 25 ++++++- growth/player.tscn | 4 +- growth/virus.gd | 14 +++- growth/virus.tscn | 68 ++++++++++--------- 11 files changed, 102 insertions(+), 51 deletions(-) diff --git a/growth/CardInjects/CursorGun/cursor_bullet.gd b/growth/CardInjects/CursorGun/cursor_bullet.gd index cb2a54f..209cc46 100644 --- a/growth/CardInjects/CursorGun/cursor_bullet.gd +++ b/growth/CardInjects/CursorGun/cursor_bullet.gd @@ -6,12 +6,21 @@ extends Area2D func _physics_process(delta): var direction = Vector2.RIGHT.rotated(self.rotation) self.position += direction * speed * delta - -func _on_body_entered(body): - if body.is_in_group("mobs"): - body.take_hit() + +func _on_area_entered(area: Area2D) -> void: + if self.get_parent().is_in_group("Virus"): + # Prevent friendly fire + return + print_debug("Cursor bullet hit %s" % area.name) + var area_parent = area.get_parent() + if (area_parent.is_in_group("Virus")): + area_parent.take_hit(1, self.position.direction_to(area.position) * 200, 1) self.queue_free() +func _on_body_entered(body): + print_debug("Cursor bullet hit %s" % body.name) + body.take_hit(1, self.position.direction_to(body.position) * 200, 1) + self.queue_free() func _on_timer_timeout() -> void: self.queue_free() diff --git a/growth/CardInjects/CursorGun/cursor_bullet.tscn b/growth/CardInjects/CursorGun/cursor_bullet.tscn index 227fbe0..ead3a0b 100644 --- a/growth/CardInjects/CursorGun/cursor_bullet.tscn +++ b/growth/CardInjects/CursorGun/cursor_bullet.tscn @@ -8,6 +8,8 @@ size = Vector2(226, 168) [node name="CursorBullet" type="Area2D"] scale = Vector2(0.1, 0.1) +collision_layer = 31 +collision_mask = 31 script = ExtResource("1_ln2dr") speed = 2000 @@ -23,5 +25,6 @@ wait_time = 5.0 one_shot = true autostart = true +[connection signal="area_entered" from="." to="." method="_on_area_entered"] [connection signal="body_entered" from="." to="." method="_on_body_entered"] [connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"] diff --git a/growth/CardInjects/CursorGun/cursor_gun_card_inject.gd b/growth/CardInjects/CursorGun/cursor_gun_card_inject.gd index a81a80f..38e61ed 100644 --- a/growth/CardInjects/CursorGun/cursor_gun_card_inject.gd +++ b/growth/CardInjects/CursorGun/cursor_gun_card_inject.gd @@ -25,16 +25,17 @@ func activate(world, activator): var target = activator.get_target_pos() var position = activator.position - position += position.direction_to(target) \ + position = position.direction_to(target) \ * clamp(position.distance_to(target), min_range, max_range) cast_timer.timeout.connect(_activate.bind(world, activator, position), CONNECT_ONE_SHOT) cast_timer.start() cooldown_timer.start() -func _activate(world, activator, position): +func _activate(_world, activator, position): var bullet = CursorBullet.instantiate() - world.add_child(bullet) + bullet.collision_mask = ~activator.collision_mask + activator.add_child(bullet) bullet.position = position bullet.look_at(activator.get_target_pos()) if activator.get_collision_layer_value(1): # player object diff --git a/growth/CardInjects/Firewall/firewall.tscn b/growth/CardInjects/Firewall/firewall.tscn index f57db6e..46b0e20 100644 --- a/growth/CardInjects/Firewall/firewall.tscn +++ b/growth/CardInjects/Firewall/firewall.tscn @@ -1,8 +1,11 @@ -[gd_scene load_steps=3 format=3 uid="uid://ddvrvdq4406l4"] +[gd_scene load_steps=4 format=3 uid="uid://ddvrvdq4406l4"] [ext_resource type="Script" uid="uid://bmt6oqrixatxt" path="res://CardInjects/Firewall/firewall.gd" id="1_qwxdp"] [ext_resource type="SpriteFrames" uid="uid://bliai1y7g52o0" path="res://assets/animations/Firewalls/firewall.tres" id="2_nlcc7"] +[sub_resource type="RectangleShape2D" id="RectangleShape2D_4b7oj"] +size = Vector2(111.33856, 61) + [node name="Firewall" type="Node2D"] script = ExtResource("1_qwxdp") @@ -14,9 +17,13 @@ frame_progress = 0.5135349 [node name="Area2D" type="Area2D" parent="."] [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +position = Vector2(3.0000005, 11) +rotation = 0.80285144 +shape = SubResource("RectangleShape2D_4b7oj") [node name="Timer" type="Timer" parent="."] process_callback = 0 +wait_time = 5.0 one_shot = true autostart = true diff --git a/growth/CardInjects/Katana/katana_card_inject.gd b/growth/CardInjects/Katana/katana_card_inject.gd index 8a0dd4b..7e44186 100644 --- a/growth/CardInjects/Katana/katana_card_inject.gd +++ b/growth/CardInjects/Katana/katana_card_inject.gd @@ -33,7 +33,7 @@ func activate(world, activator): cooldown_timer.start() -func _activate(world, activator, position): +func _activate(_world, activator, position): var katana = KatanaSlash.instantiate() var target = activator.get_target_pos() activator.add_child(katana) # KatanaSlash might have to be detached later? @@ -48,7 +48,7 @@ func _activate(world, activator, position): katana.get_node("Area2D").set_collision_layer_value(2, false) else: assert(false, "who are you, activator?") - world.add_child(katana) + # world.add_child(katana) func discard(world, activator, do_ability): ammo = max_ammo diff --git a/growth/CardInjects/Mine/mine.tscn b/growth/CardInjects/Mine/mine.tscn index 8719c59..c7a8b90 100644 --- a/growth/CardInjects/Mine/mine.tscn +++ b/growth/CardInjects/Mine/mine.tscn @@ -14,7 +14,6 @@ texture = ExtResource("2_80s1i") [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] [node name="Timer" type="Timer" parent="."] -wait_time = 300.0 one_shot = true autostart = true diff --git a/growth/hand.gd b/growth/hand.gd index 28bffda..4d7365a 100644 --- a/growth/hand.gd +++ b/growth/hand.gd @@ -42,7 +42,6 @@ func play_card(): if active_card_index >= 0 and active_card_index < slots.size(): var card = slots[active_card_index].get_node("Card") card.activate(get_node(world), get_node(player)); - print_debug("Played card %s with %s ammo remaining" % [card.title, card.get_ammo()]) # Auto-discard if out of ammo if card.get_ammo() <= 0: discard(false); diff --git a/growth/player.gd b/growth/player.gd index a4826b9..e37392b 100644 --- a/growth/player.gd +++ b/growth/player.gd @@ -27,6 +27,8 @@ var charged = false; var dash_cooldown_timer = 0; var dash_on_cooldown = false; +var knockback_timer: Timer = Timer.new() + func get_target_pos(): return self.get_global_mouse_position() @@ -73,6 +75,7 @@ func dash(): func _ready(): screen_size = get_viewport_rect().size + knockback_timer.one_shot = true func _process(delta): update_target_coords(); @@ -87,7 +90,7 @@ func _process(delta): dash_cooldown_timer = 0; # handle move_state - if move_state == MoveState.Knockback: + if knockback_timer.time_left > 0: pass elif Input.is_action_just_pressed("dash"): dash(); @@ -100,6 +103,22 @@ func _process(delta): move_and_slide(); +func take_hit(_damage, knockback_vector, knockback_strength = 1): + # Called when the player takes damage + if shield_active: + shield_active = false; + # TODO visualize shield + # $Shield.hide(); + move_state = MoveState.Knockback; + velocity = knockback_vector; + knockback_timer.start(0.2 * knockback_strength); + else: + reboot(); -func _on_timer_timeout(): - pass # Replace with function body. +func reboot(): + # Called when the player dies + # For now, just reset position and state + position = Vector2.ZERO; + velocity = Vector2.ZERO; + move_state = MoveState.Still; + # hand.discard_all(); diff --git a/growth/player.tscn b/growth/player.tscn index 3c2af90..18240dd 100644 --- a/growth/player.tscn +++ b/growth/player.tscn @@ -17,8 +17,8 @@ animations = [{ [sub_resource type="CircleShape2D" id="CircleShape2D_i3pqv"] [node name="Player" type="CharacterBody2D"] -collision_layer = 21 -collision_mask = 31 +collision_layer = 31 +collision_mask = 28 motion_mode = 1 script = ExtResource("1_4flbx") metadata/_edit_group_ = true diff --git a/growth/virus.gd b/growth/virus.gd index fbf930f..c2d2b54 100644 --- a/growth/virus.gd +++ b/growth/virus.gd @@ -1,7 +1,10 @@ extends Node2D -@export var speed = 200 # How fast the virus will move (pixels/sec). +@export var speed = 100 # How fast the virus will move (pixels/sec). @export var attack_range = 1000 # virus vision radius (pixels) +@export var max_health = 10 + +var health = max_health # a virus is instantiated as Spawning and transitions (matures) into Spawned # after a timer timeout, after which it is activated and ready to do its thing. @@ -19,6 +22,7 @@ var targets = [0] # who the virus will attack func _ready(): self.spawning_state = SpawningState.Spawning self.action_state = ActionState.Waiting + self.add_to_group("Virus") $AnimationTree.set("parameters/transition/transition_request", "processing") func _process(delta): @@ -49,3 +53,11 @@ func set_spawning(): func set_spawned(): self.spawning_state = SpawningState.Spawned + +func take_hit(damage, _knockback_vector, _knockback_strength = 1): + health -= damage + if health <= 0: + queue_free() + else: + # Flash white for now + pass \ No newline at end of file diff --git a/growth/virus.tscn b/growth/virus.tscn index e706552..9a65d91 100644 --- a/growth/virus.tscn +++ b/growth/virus.tscn @@ -40,7 +40,6 @@ input_2/break_loop_at_end = false input_2/reset = true [sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_lk7jo"] -graph_offset = Vector2(-232.38345, 122.08092) nodes/output/position = Vector2(580, 300) nodes/Animation/node = SubResource("AnimationNodeAnimation_7ae1t") nodes/Animation/position = Vector2(80, 140) @@ -52,6 +51,38 @@ nodes/transition/position = Vector2(360, 300) "nodes/Animation 2/position" = Vector2(80, 360) node_connections = [&"output", 0, &"transition", &"transition", 0, &"Animation", &"transition", 1, &"Animation 2", &"transition", 2, &"Animation 3"] +[sub_resource type="Animation" id="Animation_ob56v"] +resource_name = "virus_idle" +loop_mode = 1 +tracks/0/type = "method" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../AnimatedSprite2D") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [&"idle", 1.0, false], +"method": &"play" +}] +} +tracks/1/type = "method" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("..") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"set_spawned" +}] +} + [sub_resource type="Animation" id="Animation_7ae1t"] resource_name = "virus_processing" length = 3.7875 @@ -103,38 +134,6 @@ tracks/0/keys = { }] } -[sub_resource type="Animation" id="Animation_ob56v"] -resource_name = "virus_idle" -loop_mode = 1 -tracks/0/type = "method" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("../AnimatedSprite2D") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"values": [{ -"args": [&"idle", 1.0, false], -"method": &"play" -}] -} -tracks/1/type = "method" -tracks/1/imported = false -tracks/1/enabled = true -tracks/1/path = NodePath("..") -tracks/1/interp = 1 -tracks/1/loop_wrap = true -tracks/1/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"values": [{ -"args": [], -"method": &"set_spawned" -}] -} - [sub_resource type="AnimationLibrary" id="AnimationLibrary_lk7jo"] _data = { &"virus_idle": SubResource("Animation_ob56v"), @@ -231,6 +230,7 @@ animations = [{ size = Vector2(128, 128) [node name="Virus" type="Node2D"] +position = Vector2(0, -1) script = ExtResource("1_5nuwd") [node name="AnimationTree" type="AnimationTree" parent="."] @@ -253,6 +253,8 @@ animation = &"spawn" autoplay = "grow" [node name="Area2D" type="Area2D" parent="."] +collision_layer = 31 +collision_mask = 31 [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] shape = SubResource("RectangleShape2D_ifgnm")