diff --git a/growth/BaseCard/BaseCard.gd b/growth/BaseCard/BaseCard.gd index dbc2767..ce3868f 100644 --- a/growth/BaseCard/BaseCard.gd +++ b/growth/BaseCard/BaseCard.gd @@ -18,7 +18,15 @@ func _ready() -> void: func activate(world, activator): for behavior in $Behaviors.get_children(): behavior.activate(world, activator) - + func discard(world, activator): for behavior in $Behaviors.get_children(): behavior.discard(world, activator) + if "ammo" in behavior: # Wtf? + behavior.ammo = behavior.max_ammo + +func get_ammo(): + for behavior in $Behaviors.get_children(): + if behavior.has_method("get_ammo"): + return behavior.get_ammo() + return -1 diff --git a/growth/CardInjects/Firewall/firewall_card_inject.gd b/growth/CardInjects/Firewall/firewall_card_inject.gd index 1215270..f87d4c1 100644 --- a/growth/CardInjects/Firewall/firewall_card_inject.gd +++ b/growth/CardInjects/Firewall/firewall_card_inject.gd @@ -1,8 +1,8 @@ extends Node @export var FireWall: PackedScene -@export var max_range = 10 -@export var min_range = 5 +@export var max_range = 70 +@export var min_range = 50 @export var max_ammo = 5 var ammo = max_ammo diff --git a/growth/CardInjects/Katana/katana.gd b/growth/CardInjects/Katana/katana.gd new file mode 100644 index 0000000..e251cf8 --- /dev/null +++ b/growth/CardInjects/Katana/katana.gd @@ -0,0 +1 @@ +extends Node2D diff --git a/growth/CardInjects/Katana/katana.gd.uid b/growth/CardInjects/Katana/katana.gd.uid new file mode 100644 index 0000000..d0417d7 --- /dev/null +++ b/growth/CardInjects/Katana/katana.gd.uid @@ -0,0 +1 @@ +uid://ba40wm75ry2oh diff --git a/growth/CardInjects/Katana/katana.tscn b/growth/CardInjects/Katana/katana.tscn new file mode 100644 index 0000000..ece1816 --- /dev/null +++ b/growth/CardInjects/Katana/katana.tscn @@ -0,0 +1,91 @@ +[gd_scene load_steps=15 format=3 uid="uid://415yw4i180tb"] + +[ext_resource type="Script" uid="uid://ba40wm75ry2oh" path="res://CardInjects/Katana/katana.gd" id="1_1dbc3"] +[ext_resource type="Texture2D" uid="uid://n676fc0oqssw" path="res://assets/animations/Katana_slash_1/Slash 1.png" id="2_b0k4l"] +[ext_resource type="Texture2D" uid="uid://brrakxqc40cx3" path="res://assets/animations/Katana_slash_1/Slash 2.png" id="3_rqa0t"] +[ext_resource type="Texture2D" uid="uid://0tivfj0mlwu4" path="res://assets/animations/Katana_slash_1/Slash 3.png" id="4_vyhi5"] +[ext_resource type="Texture2D" uid="uid://scrlfav4vsq0" path="res://assets/animations/Katana_slash_1/Slash 4.png" id="5_4klwf"] +[ext_resource type="Texture2D" uid="uid://bsrrmga720ml" path="res://assets/animations/Katana_slash_1/Slash 5.png" id="6_he2lf"] +[ext_resource type="Texture2D" uid="uid://bw1pmpji38len" path="res://assets/animations/Katana_slash_1/Slash 6.png" id="7_0vlic"] +[ext_resource type="Texture2D" uid="uid://b71m60416ssrh" path="res://assets/animations/Katana_slash_1/Slash 7.png" id="8_sj3so"] +[ext_resource type="Texture2D" uid="uid://b3wk8akdefirx" path="res://assets/animations/Katana_slash_1/Slash 8.png" id="9_kuojl"] +[ext_resource type="Texture2D" uid="uid://b0ah2jqrw5g8m" path="res://assets/animations/Katana_slash_1/Slash 10.png" id="10_fakx8"] + +[sub_resource type="Animation" id="Animation_b0k4l"] +resource_name = "katana_slash" +tracks/0/type = "method" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0.33333334), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"queue_free" +}] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_rqa0t"] +_data = { +&"katana_slash": SubResource("Animation_b0k4l") +} + +[sub_resource type="SpriteFrames" id="SpriteFrames_wdw6g"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": ExtResource("2_b0k4l") +}, { +"duration": 1.0, +"texture": ExtResource("3_rqa0t") +}, { +"duration": 1.0, +"texture": ExtResource("4_vyhi5") +}, { +"duration": 1.0, +"texture": ExtResource("5_4klwf") +}, { +"duration": 1.0, +"texture": ExtResource("6_he2lf") +}, { +"duration": 1.0, +"texture": ExtResource("7_0vlic") +}, { +"duration": 1.0, +"texture": ExtResource("8_sj3so") +}, { +"duration": 1.0, +"texture": ExtResource("9_kuojl") +}, { +"duration": 1.0, +"texture": ExtResource("10_fakx8") +}], +"loop": false, +"name": &"default", +"speed": 30.0 +}] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_b0k4l"] +size = Vector2(158.5, 355.5) + +[node name="Katana" type="Node2D"] +script = ExtResource("1_1dbc3") + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +&"": SubResource("AnimationLibrary_rqa0t") +} +autoplay = "katana_slash" + +[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."] +sprite_frames = SubResource("SpriteFrames_wdw6g") +autoplay = "default" + +[node name="Area2D" type="Area2D" parent="."] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +position = Vector2(1, 1) +shape = SubResource("RectangleShape2D_b0k4l") diff --git a/growth/CardInjects/Katana/katana_card_inject.gd b/growth/CardInjects/Katana/katana_card_inject.gd new file mode 100644 index 0000000..48a79a9 --- /dev/null +++ b/growth/CardInjects/Katana/katana_card_inject.gd @@ -0,0 +1,28 @@ +extends Node + +@export var KatanaSlash: PackedScene +@export var max_range = 50 +@export var min_range = 50 +@export var max_ammo = 20 +var ammo = max_ammo + +func activate(world, activator): + var katana = KatanaSlash.instantiate() + var target = activator.get_target_pos() + katana.position = activator.position + katana.position += katana.position.direction_to(target) \ + * clamp(katana.position.distance_to(target), min_range, max_range) + katana.look_at(target) + if activator.get_collision_layer_value(1): # player object + katana.get_node("Area2D").set_collision_layer_value(1, false) + katana.get_node("Area2D").set_collision_layer_value(2, true) + elif activator.get_collision_layer_value(2): # enemy object + katana.get_node("Area2D").set_collision_layer_value(1, true) + katana.get_node("Area2D").set_collision_layer_value(2, false) + else: + assert(false, "who are you, activator?") + world.add_child(katana) + + +func discard(world, activator): + pass diff --git a/growth/CardInjects/Katana/katana_card_inject.gd.uid b/growth/CardInjects/Katana/katana_card_inject.gd.uid new file mode 100644 index 0000000..642ce05 --- /dev/null +++ b/growth/CardInjects/Katana/katana_card_inject.gd.uid @@ -0,0 +1 @@ +uid://cts63mtlco6yj diff --git a/growth/CardInjects/Katana/katana_card_inject.tscn b/growth/CardInjects/Katana/katana_card_inject.tscn new file mode 100644 index 0000000..51b0ba1 --- /dev/null +++ b/growth/CardInjects/Katana/katana_card_inject.tscn @@ -0,0 +1,8 @@ +[gd_scene load_steps=3 format=3 uid="uid://hgf0o7ugi77q"] + +[ext_resource type="Script" uid="uid://cts63mtlco6yj" path="res://CardInjects/Katana/katana_card_inject.gd" id="1_8j8fv"] +[ext_resource type="PackedScene" uid="uid://415yw4i180tb" path="res://CardInjects/Katana/katana.tscn" id="2_u2uea"] + +[node name="KatanaCardInject" type="Node"] +script = ExtResource("1_8j8fv") +KatanaSlash = ExtResource("2_u2uea") diff --git a/growth/CardInjects/Mine/mine.gd b/growth/CardInjects/Mine/mine.gd new file mode 100644 index 0000000..f1e6910 --- /dev/null +++ b/growth/CardInjects/Mine/mine.gd @@ -0,0 +1,5 @@ +extends Node2D + + +func _on_timer_timeout(): + self.queue_free() diff --git a/growth/CardInjects/Mine/mine.gd.uid b/growth/CardInjects/Mine/mine.gd.uid new file mode 100644 index 0000000..bd121d3 --- /dev/null +++ b/growth/CardInjects/Mine/mine.gd.uid @@ -0,0 +1 @@ +uid://b3jims0gq4tg5 diff --git a/growth/CardInjects/Mine/mine.tscn b/growth/CardInjects/Mine/mine.tscn new file mode 100644 index 0000000..8719c59 --- /dev/null +++ b/growth/CardInjects/Mine/mine.tscn @@ -0,0 +1,21 @@ +[gd_scene load_steps=3 format=3 uid="uid://umv7m1lf4x6b"] + +[ext_resource type="Script" uid="uid://b3jims0gq4tg5" path="res://CardInjects/Mine/mine.gd" id="1_mj2xh"] +[ext_resource type="Texture2D" uid="uid://dmq8shsoq55dx" path="res://assets/icons/Mine_symbol.png" id="2_80s1i"] + +[node name="Mine" type="Node2D"] +script = ExtResource("1_mj2xh") + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = ExtResource("2_80s1i") + +[node name="Area2D" type="Area2D" parent="."] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] + +[node name="Timer" type="Timer" parent="."] +wait_time = 300.0 +one_shot = true +autostart = true + +[connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"] diff --git a/growth/CardInjects/Mine/mine_card_inject.gd b/growth/CardInjects/Mine/mine_card_inject.gd new file mode 100644 index 0000000..a3c8b5e --- /dev/null +++ b/growth/CardInjects/Mine/mine_card_inject.gd @@ -0,0 +1,26 @@ +extends Node + +@export var Mine: PackedScene +@export var max_range = 1500 +@export var min_range = 15 +@export var max_ammo = 5 +var ammo = max_ammo + +func activate(world, activator): + var mine = Mine.instantiate() + var target = activator.get_target_pos() + mine.position = activator.position + mine.position += mine.position.direction_to(target) \ + * clamp(mine.position.distance_to(target), min_range, max_range) + if activator.get_collision_layer_value(1): # player object + mine.get_node("Area2D").set_collision_layer_value(1, false) + mine.get_node("Area2D").set_collision_layer_value(2, true) + elif activator.get_collision_layer_value(2): # enemy object + mine.get_node("Area2D").set_collision_layer_value(1, true) + mine.get_node("Area2D").set_collision_layer_value(2, false) + else: + assert(false, "who are you, activator?") + world.add_child(mine) + +func discard(world, activator): + pass diff --git a/growth/CardInjects/Mine/mine_card_inject.gd.uid b/growth/CardInjects/Mine/mine_card_inject.gd.uid new file mode 100644 index 0000000..5d92285 --- /dev/null +++ b/growth/CardInjects/Mine/mine_card_inject.gd.uid @@ -0,0 +1 @@ +uid://hdyom3r5ebee diff --git a/growth/CardInjects/Mine/mine_card_inject.tscn b/growth/CardInjects/Mine/mine_card_inject.tscn new file mode 100644 index 0000000..a813b3b --- /dev/null +++ b/growth/CardInjects/Mine/mine_card_inject.tscn @@ -0,0 +1,8 @@ +[gd_scene load_steps=3 format=3 uid="uid://dbfulrblm07v3"] + +[ext_resource type="Script" uid="uid://hdyom3r5ebee" path="res://CardInjects/Mine/mine_card_inject.gd" id="1_oct4p"] +[ext_resource type="PackedScene" uid="uid://umv7m1lf4x6b" path="res://CardInjects/Mine/mine.tscn" id="2_wv1jf"] + +[node name="MineCardInject" type="Node"] +script = ExtResource("1_oct4p") +Mine = ExtResource("2_wv1jf") diff --git a/growth/Cards/KatanaCard.tscn b/growth/Cards/KatanaCard.tscn new file mode 100644 index 0000000..ede2334 --- /dev/null +++ b/growth/Cards/KatanaCard.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=4 format=3 uid="uid://cx7jna1pp3mrp"] + +[ext_resource type="PackedScene" uid="uid://b0g5wd4n3py3x" path="res://BaseCard/BaseCard.tscn" id="1_odiq1"] +[ext_resource type="PackedScene" uid="uid://hgf0o7ugi77q" path="res://CardInjects/Katana/katana_card_inject.tscn" id="2_7xay5"] +[ext_resource type="Texture2D" uid="uid://3y6mg4kulohd" path="res://assets/icons/The_Katana_2_symbol.png" id="3_3cjjn"] + +[node name="Card" instance=ExtResource("1_odiq1")] +behaviors = [ExtResource("2_7xay5")] +art = ExtResource("3_3cjjn") +title = "Katana" +description = "while you were asleep, i studied the blade" diff --git a/growth/Cards/MineCard.tscn b/growth/Cards/MineCard.tscn new file mode 100644 index 0000000..1db6ac3 --- /dev/null +++ b/growth/Cards/MineCard.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=4 format=3 uid="uid://dck7bp1b7553t"] + +[ext_resource type="PackedScene" uid="uid://b0g5wd4n3py3x" path="res://BaseCard/BaseCard.tscn" id="1_f6n5b"] +[ext_resource type="PackedScene" uid="uid://dbfulrblm07v3" path="res://CardInjects/Mine/mine_card_inject.tscn" id="2_efd40"] +[ext_resource type="Texture2D" uid="uid://dmq8shsoq55dx" path="res://assets/icons/Mine_symbol.png" id="3_gte2f"] + +[node name="Card" instance=ExtResource("1_f6n5b")] +behaviors = [ExtResource("2_efd40")] +art = ExtResource("3_gte2f") +title = "Mine" +description = "watch em blow!" diff --git a/growth/hand.gd b/growth/hand.gd index 4f11bea..8b22606 100644 --- a/growth/hand.gd +++ b/growth/hand.gd @@ -2,31 +2,32 @@ extends Control @export var player: NodePath @export var world: NodePath -@export var drawpile: Array[PackedScene] = [ - preload("res://Cards/FirewallCard.tscn"), - preload("res://Cards/FirewallCard.tscn"), - preload("res://Cards/CursorGunCard.tscn"), - preload("res://Cards/CursorGunCard.tscn"), - preload("res://Cards/DashCard.tscn"), - preload("res://Cards/DashCard.tscn"), - #preload("res://Cards/ShieldCard.tscn"), - #preload("res://Cards/ShieldCard.tscn"), - #preload("res://Cards/OverclockCard.tscn"), - #preload("res://Cards/OverclockCard.tscn"), +@export var hand_size = 3 +@export var drawpile: Array = [ + preload("res://Cards/FirewallCard.tscn").instantiate(), + # preload("res://Cards/FirewallCard.tscn").instantiate(), + preload("res://Cards/CursorGunCard.tscn").instantiate(), + # preload("res://Cards/CursorGunCard.tscn").instantiate(), + preload("res://Cards/DashCard.tscn").instantiate(), + # preload("res://Cards/DashCard.tscn").instantiate(), + preload("res://Cards/MineCard.tscn").instantiate(), + # preload("res://Cards/MineCard.tscn").instantiate(), + #preload("res://Cards/ShieldCard.tscn").instantiate(), + #preload("res://Cards/ShieldCard.tscn").instantiate(), + #preload("res://Cards/OverclockCard.tscn").instantiate(), + #preload("res://Cards/OverclockCard.tscn").instantiate(), ] - + var active_card_index = 0 -const discard_pile = []; +var discard_pile = []; func _ready() -> void: - for card in drawpile: - card.instantiate() drawpile.shuffle(); - #for i in range(get_node(player).hand_size): - #draw_card() + for i in range(hand_size - get_cards().size()): + draw_card() -func _process(delta): +func _process(_delta): if Input.is_action_pressed("play_card"): play_card() if Input.is_action_just_pressed("cycle_card_left"): @@ -39,27 +40,37 @@ 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(active_card_index) + if card.get_ammo() <= 0: + discard(false); -func discard(): + +func discard(do_ability = true): var cards = get_cards(); if active_card_index >= 0 and active_card_index < cards.size(): var card = cards[active_card_index] - card.discard(get_node(world), get_node(player)) + if do_ability: + card.discard(get_node(world), get_node(player)) discard_pile.append(card) - get_card_container().remove_child(card) + card.get_parent().remove_child(card) #active_card_index = min(active_card_index, hand.size() - 1); draw_card(); func cycle_card(index_shift): - active_card_index = (active_card_index + index_shift) % 3 - set_active(active_card_index) + var t = get_cards().size() + if t > 0: + active_card_index = (active_card_index + index_shift) % t + highlight_card(active_card_index) + else: + draw_card(); -func set_active(n): - for i in range(2): - set_inactive((n + i + 1) % 3) + +func highlight_card(n): + var t = get_cards().size() + for i in range(1, t): + set_inactive((n + i) % t) + var slot = get_slot(n) slot.set_z_index(1) var tween := create_tween() @@ -74,15 +85,26 @@ func set_inactive(n): func get_slot(n): return get_children()[n] - func draw_card(): - if drawpile.size() == 0: + var held_card_count = get_cards().size() + if held_card_count == 0: shuffle_deck(); - if drawpile.size() > 0 and get_cards().size() < get_node(player).hand_size: - var card = drawpile.pop_back(); - if active_card_index == -1: - active_card_index = 0; - get_card_container().add_child(card) + if drawpile.size() > 0 and held_card_count < hand_size: + for i in range(hand_size - held_card_count): + var card = drawpile.pop_back(); + if active_card_index == -1: + active_card_index = 0; + var empty_slots = get_card_container().get_children().filter(func(slot): return not slot.has_method("get_node") or slot.get_node_or_null("Card") == null) + if empty_slots.size() > 0: + empty_slots[0].add_child(card) + else: + var first_filled_slot_index = -1 + var slots = get_card_container().get_children() + for i in range(slots.size()): + if slots[i].has_method("get_node") and slots[i].get_node_or_null("Card") != null: + first_filled_slot_index = i + break + active_card_index = first_filled_slot_index # TODO: Reboot mechanics func shuffle_deck(): @@ -92,10 +114,10 @@ func shuffle_deck(): active_card_index = 0; func get_cards() -> Array: - return get_card_container().get_children() + return get_card_container().get_children().map(func(c): return c.get_node_or_null("Card")).filter(func(c): return c != null) func get_card_container(): - return $HBoxContainer + return $"." func get_active_card(): return get_cards().get(active_card_index).get_node("Card") diff --git a/growth/level.tscn b/growth/level.tscn index e019d92..ad366e0 100644 --- a/growth/level.tscn +++ b/growth/level.tscn @@ -4,7 +4,7 @@ [ext_resource type="PackedScene" uid="uid://bsv3h2lpv7h77" path="res://virus.tscn" id="2_oi3di"] [ext_resource type="PackedScene" uid="uid://bldi3fw0vmlu3" path="res://music.tscn" id="3_oi3di"] [ext_resource type="TileSet" uid="uid://c20bl25rqyf68" path="res://assets/tiles/new_tile_set.tres" id="4_0b4ue"] -[ext_resource type="PackedScene" uid="uid://co8jnr2dew5ts" path="res://hand.tscn" id="5_f2txt"] +[ext_resource type="PackedScene" uid="uid://cpp7v4jp8kt74" path="res://hand.tscn" id="5_f2txt"] [node name="Level" type="Node2D"] @@ -15,7 +15,6 @@ tile_set = ExtResource("4_0b4ue") [node name="Player" parent="." instance=ExtResource("1_vonw3")] position = Vector2(-1200, 0) -hand = [null] [node name="Virus" parent="." instance=ExtResource("2_oi3di")] @@ -25,3 +24,4 @@ scale = Vector2(2, 2) [node name="CanvasLayer" type="CanvasLayer" parent="."] [node name="Hand" parent="CanvasLayer" instance=ExtResource("5_f2txt")] +unique_name_in_owner = true diff --git a/growth/player.gd b/growth/player.gd index f7422d4..ff8476c 100644 --- a/growth/player.gd +++ b/growth/player.gd @@ -6,16 +6,15 @@ enum MoveState {Still, Moving, Dashing, Knockback} @export var speed = 200 # How fast the player will move (pixels/sec). @export var dash_cooldown = 0.3 -@export var hand_size = 3 @onready var camera: Camera2D = %PlayerCamera @onready var sprite: AnimatedSprite2D = $PlayerSprite +@onready var hand: Control = %Hand; var shield_active = true; var move_direction = Vector2.ZERO; var target = Vector2.ZERO # The position of the player's cursor. -@export var hand: Control; var screen_size # Size of the game window. var action_state = ActionState.None @@ -65,28 +64,15 @@ func charge(): charge_level = max(charge_level - charge_rate * 2, 0); func dash(): - var card = hand.get_active_card(); - if not card or dash_on_cooldown: + if dash_on_cooldown: return; - hand.discard(self); # Must set move_state at start and end of dash + hand.discard(); # Must set move_state at start and end of dash dash_on_cooldown = true; -func draw_card(): - #if drawpile.size() == 0: - #shuffle_deck(); - #if drawpile.size() > 0 and hand.size() < hand_size: - #var card = drawpile.pop_back(); - #hand.append(card); - #if active_card_index == -1: - #active_card_index = 0; - pass - func _ready(): screen_size = get_viewport_rect().size - #while (hand.size() < hand_size and drawpile.size() > 0): - #draw_card(); func _process(delta): update_target_coords();