diff --git a/growth/BaseCard/BaseCard.gd b/growth/BaseCard/BaseCard.gd index d1c20d2..b490624 100644 --- a/growth/BaseCard/BaseCard.gd +++ b/growth/BaseCard/BaseCard.gd @@ -19,10 +19,9 @@ func activate(world, activator): for behavior in $Behaviors.get_children(): behavior.activate(world, activator) -func discard(world, activator): +func discard(world, activator, do_ability): for behavior in $Behaviors.get_children(): - behavior.discard(world, activator) - behavior.ammo = behavior.max_ammo + behavior.discard(world, activator, do_ability) func get_ammo(): for behavior in $Behaviors.get_children(): diff --git a/growth/CardInjects/CursorGun/cursor_bullet.tscn b/growth/CardInjects/CursorGun/cursor_bullet.tscn index 6848b54..227fbe0 100644 --- a/growth/CardInjects/CursorGun/cursor_bullet.tscn +++ b/growth/CardInjects/CursorGun/cursor_bullet.tscn @@ -7,7 +7,9 @@ size = Vector2(226, 168) [node name="CursorBullet" type="Area2D"] +scale = Vector2(0.1, 0.1) script = ExtResource("1_ln2dr") +speed = 2000 [node name="Sprite2D" type="Sprite2D" parent="."] texture = ExtResource("1_g08wh") diff --git a/growth/CardInjects/CursorGun/cursor_gun_card_inject.gd b/growth/CardInjects/CursorGun/cursor_gun_card_inject.gd index 33c4304..a81a80f 100644 --- a/growth/CardInjects/CursorGun/cursor_gun_card_inject.gd +++ b/growth/CardInjects/CursorGun/cursor_gun_card_inject.gd @@ -1,23 +1,54 @@ extends Node @export var CursorBullet: PackedScene = preload("res://CardInjects/CursorGun/cursor_bullet.tscn") +@export var max_range = 50 +@export var min_range = 50 @export var max_ammo = 30 +@export var cast_time = 0.05 +@export var cooldown_time = 0.1 + var ammo = max_ammo +var cast_timer: Timer = Timer.new() +var cooldown_timer: Timer = Timer.new() + +func _ready(): + add_child(cast_timer) + cast_timer.wait_time = cast_time + cast_timer.one_shot = true + add_child(cooldown_timer) + cooldown_timer.wait_time = cooldown_time + cooldown_timer.one_shot = true func activate(world, activator): - var target: Vector2 = activator.get_target_pos() + if cooldown_timer.time_left: + return + + var target = activator.get_target_pos() + var position = activator.position + 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): var bullet = CursorBullet.instantiate() world.add_child(bullet) - bullet.position = activator.position - bullet.look_at(target) + bullet.position = position + bullet.look_at(activator.get_target_pos()) if activator.get_collision_layer_value(1): # player object bullet.set_collision_layer_value (1, false) bullet.set_collision_layer_value(2, true) + ammo -= 1 elif activator.get_collision_layer_value(2): # enemy object bullet.set_collision_layer_value(1, true) bullet.set_collision_layer_value(2, false) else: assert(false, "who are you, activator?") -func discard(world, activator): - pass +func discard(world, activator, do_ability): + ammo = max_ammo + +func get_ammo(): + return ammo diff --git a/growth/CardInjects/Firewall/firewall_card_inject.gd b/growth/CardInjects/Firewall/firewall_card_inject.gd index f87d4c1..b1298bd 100644 --- a/growth/CardInjects/Firewall/firewall_card_inject.gd +++ b/growth/CardInjects/Firewall/firewall_card_inject.gd @@ -4,17 +4,41 @@ extends Node @export var max_range = 70 @export var min_range = 50 @export var max_ammo = 5 +@export var cast_time = 0.1 +@export var cooldown_time = 0.3 + var ammo = max_ammo +var cast_timer: Timer = Timer.new() +var cooldown_timer: Timer = Timer.new() + +func _ready(): + add_child(cast_timer) + cast_timer.wait_time = cast_time + cast_timer.one_shot = true + add_child(cooldown_timer) + cooldown_timer.wait_time = cooldown_time + cooldown_timer.one_shot = true func activate(world, activator): - var firewall = FireWall.instantiate() + if not Input.is_action_just_pressed("play_card") or cooldown_timer.time_left: + return + var target = activator.get_target_pos() - firewall.position = activator.position - firewall.position += firewall.position.direction_to(target) \ - * clamp(firewall.position.distance_to(target), min_range, max_range) + var position = activator.position + 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): + var firewall = FireWall.instantiate() + firewall.position = position if activator.get_collision_layer_value(1): # player object firewall.get_node("Area2D").set_collision_layer_value(1, false) firewall.get_node("Area2D").set_collision_layer_value(2, true) + ammo -= 1 elif activator.get_collision_layer_value(2): # enemy object firewall.get_node("Area2D").set_collision_layer_value(1, true) firewall.get_node("Area2D").set_collision_layer_value(2, false) @@ -23,5 +47,9 @@ func activate(world, activator): world.add_child(firewall) -func discard(world, activator): - pass + +func discard(world, activator, do_ability): + ammo = max_ammo + +func get_ammo(): + return ammo diff --git a/growth/CardInjects/Katana/katana_card_inject.gd b/growth/CardInjects/Katana/katana_card_inject.gd index 48a79a9..8a0dd4b 100644 --- a/growth/CardInjects/Katana/katana_card_inject.gd +++ b/growth/CardInjects/Katana/katana_card_inject.gd @@ -4,18 +4,45 @@ extends Node @export var max_range = 50 @export var min_range = 50 @export var max_ammo = 20 +@export var cast_time = 0.2 +@export var cooldown_time = 0.5 + var ammo = max_ammo +var cast_timer: Timer = Timer.new() +var cooldown_timer: Timer = Timer.new() + +func _ready(): + add_child(cast_timer) + cast_timer.wait_time = cast_time + cast_timer.one_shot = true + add_child(cooldown_timer) + cooldown_timer.wait_time = cooldown_time + cooldown_timer.one_shot = true func activate(world, activator): + if cooldown_timer.time_left: + return + + var target = activator.get_target_pos() + var position = activator.position + 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): 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) + activator.add_child(katana) # KatanaSlash might have to be detached later? + katana.position = position 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) + ammo -= 1 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) @@ -23,6 +50,8 @@ func activate(world, activator): assert(false, "who are you, activator?") world.add_child(katana) +func discard(world, activator, do_ability): + ammo = max_ammo -func discard(world, activator): - pass +func get_ammo(): + return ammo diff --git a/growth/CardInjects/Mine/mine_card_inject.gd b/growth/CardInjects/Mine/mine_card_inject.gd index a3c8b5e..15b66eb 100644 --- a/growth/CardInjects/Mine/mine_card_inject.gd +++ b/growth/CardInjects/Mine/mine_card_inject.gd @@ -4,17 +4,41 @@ extends Node @export var max_range = 1500 @export var min_range = 15 @export var max_ammo = 5 +@export var cast_time = 0.5 +@export var cooldown_time = 1.0 + var ammo = max_ammo +var cast_timer: Timer = Timer.new() +var cooldown_timer: Timer = Timer.new() + +func _ready(): + add_child(cast_timer) + cast_timer.wait_time = cast_time + cast_timer.one_shot = true + add_child(cooldown_timer) + cooldown_timer.wait_time = cooldown_time + cooldown_timer.one_shot = true func activate(world, activator): - var mine = Mine.instantiate() + if not Input.is_action_just_pressed("play_card") or cooldown_timer.time_left: + return + 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) + var position = activator.position + 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): + var mine = Mine.instantiate() + mine.position = position 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) + ammo -= 1 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) @@ -22,5 +46,8 @@ func activate(world, activator): assert(false, "who are you, activator?") world.add_child(mine) -func discard(world, activator): - pass +func discard(world, activator, do_ability): + ammo = max_ammo + +func get_ammo(): + return ammo diff --git a/growth/hand.gd b/growth/hand.gd index 4e5bd62..6b92162 100644 --- a/growth/hand.gd +++ b/growth/hand.gd @@ -8,7 +8,7 @@ extends Control # 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/DashCard.tscn").instantiate(), preload("res://Cards/MineCard.tscn").instantiate(), # preload("res://Cards/MineCard.tscn").instantiate(), @@ -16,6 +16,8 @@ extends Control #preload("res://Cards/ShieldCard.tscn").instantiate(), #preload("res://Cards/OverclockCard.tscn").instantiate(), #preload("res://Cards/OverclockCard.tscn").instantiate(), + preload("res://Cards/KatanaCard.tscn").instantiate(), + # preload("res://Cards/KatanaCard.tscn").instantiate(), ] var active_card_index = 0 @@ -24,7 +26,7 @@ var discard_pile = []; func _ready() -> void: drawpile.shuffle(); - for i in range(hand_size - get_cards().size()): + for i in range(hand_size - get_held_cards().size()): draw_card() func _process(_delta): @@ -40,49 +42,57 @@ 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); func discard(do_ability = true): + print_debug("Discarding card at index %s with name %s" % [active_card_index, get_cards().get(active_card_index).title]) var cards = get_cards(); if active_card_index >= 0 and active_card_index < cards.size(): var card = cards[active_card_index] - if do_ability: - card.discard(get_node(world), get_node(player)) + card.discard(get_node(world), get_node(player), do_ability) discard_pile.append(card) card.get_parent().remove_child(card) #active_card_index = min(active_card_index, hand.size() - 1); draw_card(); + func cycle_card(index_shift): - if get_cards().size() > 0: - active_card_index = (active_card_index + index_shift) % get_cards().size(); - else: - draw_card(); + var active_card_indices = get_held_cards().map(func(card): return card.get_parent().get_index()) + print_debug("Active card indices: %s" % [active_card_indices]) + if active_card_indices.size() > 0: + var result_index = active_card_index + index_shift + # Wrap around the result index within the hand size + if result_index < 0: + result_index += hand_size + elif result_index >= hand_size: + result_index -= hand_size + if result_index in active_card_indices: + active_card_index = result_index + else: + active_card_index = active_card_indices[0] + else: + push_warning("No active cards to cycle through!") + print_debug("Current active card index: %s" % [active_card_index]) + func draw_card(): - var held_card_count = get_cards().size() + var held_card_count = get_held_cards().size() if held_card_count == 0: shuffle_deck(); 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 + cycle_card(-1) # TODO: Reboot mechanics func shuffle_deck(): @@ -92,10 +102,13 @@ func shuffle_deck(): active_card_index = 0; func get_cards() -> Array: - return get_card_container().get_children().map(func(c): return c.get_node_or_null("Card")).filter(func(c): return c != null) + return get_card_container().get_children().map(func(c): return c.get_node_or_null("Card")) + +func get_held_cards() -> Array: + return get_cards().filter(func(c): return c != null) func get_card_container(): return $HBoxContainer func get_active_card(): - return get_cards().get(active_card_index).get_node("Card") + return get_cards().get(active_card_index).get_node_or_null("Card")