Skip to content

Commit

Permalink
Deck animation and layout (#25)
Browse files Browse the repository at this point in the history
* Add CardMovementComponent

-Add states, but they don't do anything yet. Just lerp to desired position
-Replace LerpComponent on Card scene

* Change CardContainer and CardWorld to Control

Change from Node2D to Control, this way we can anchor the CardContainer to the bottom of the screen

* Add card draw/discard queue system

Cards now draw and discard in a queue. To remove or draw a card, it is first added to a queue. Queued cards get removed/added from the queue on a looping timer

-Cards are removed from draw pile immediately when a draw is requested. They are added to the queue so they can be spawned async
-Cards are added to the discard pile immediately when a discard is requested. They are added to the queue to be destroyed async.
This means that cards technically exist in the draw/discard immediately when the request is given, but the world versions of the cards may spawn/destroy at a later time.

* Add CardMovementState resource

-Add CardMovementState as a Resource. So each state will be a separate file
-Added child states InHand, MovingToHand, and Discarding
-Added CardState properties which gives values for the card states
-Added EasingConstants which is string constants used for easing

* Add better card separation

Cards now separate based on a max and min value. Cards will squish closer together if there are a lot of cards in your hand. If you only have a small amount of cards in your hand, they will be centered

* Fix z-ordering of cards

Cards are moved to the top of the hierarchy if they are hovered. This makes it to where cards below this card can't be hovered.

* Other cards scoot out of the way when you hover one

When you hover a card, other cards in your hand scoot out of the way to give room for the hovered card

* Add y-offset and rotation curve to cards in hand

* Add HOVERED and QUEUED states

* Remove state switch in CardContainer

* Smooth rotation Hover and Queued states

* Organize state values. Fix MOVING_TO_HAND state

MOVING_TO_HAND state was not easing to the correct position

* Fix offset in QUEUED

* Move discard and draw timers

Moved timers to the end of the draw queue functions so the cards aren't discarded and drawn with a starting delay

* Naming cleanup. Fix weird movement with discarding state

* Fix movement issue with focus card

Focus card not getting set to null when played

* Ease rotation on discarding state

* Bind input only when the card is finished moving

* Restrict end turn button press

Only allow when cards are finished dealing and you have no card queued

* Static typing and cleanup

* Fix tests by adding on_cards_finished_dealing

Wait for cards to finish dealing before checking cards in test_cards

Removed PhaseManager.on_game_start check in test_health because the tests would never start. Since test_health isn't the first test anymore it never recieved the signal. Wasn't needed anyways

* Change CardStateProperties to Resource instead of Node

* Further commenting and cleanup

* Issue-25: Update naming for _state_not_null(), clean up readability for pulling card to start discard animation

* Issue-25: Rename LERP_SPEED to MOVE_SPEED for readability, added active_cards array to determine if all active cards are done doing their action

* Issue-12: Update active_cards from an array to just a single CardWorld object

---------

Co-authored-by: tynutsathitya <[email protected]>
  • Loading branch information
cheesefrycook and Tysterman74 authored Dec 27, 2023
1 parent 3e2535a commit f0803c5
Show file tree
Hide file tree
Showing 27 changed files with 715 additions and 93 deletions.
37 changes: 28 additions & 9 deletions #Scenes/TestingScene.tscn
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
[gd_scene load_steps=14 format=3 uid="uid://87fedoq257xg"]
[gd_scene load_steps=17 format=3 uid="uid://b60uabg68ra1l"]

[ext_resource type="PackedScene" uid="uid://clmg3l3n28x38" path="res://Entity/Player/Player.tscn" id="3_4psp7"]
[ext_resource type="PackedScene" uid="uid://dpjfy4pv0vxst" path="res://Cards/CardContainer.tscn" id="3_e7sws"]
[ext_resource type="Resource" uid="uid://dxgoopi1roxu4" path="res://Cards/Resource/Card_Damage.tres" id="4_uiqnj"]
[ext_resource type="Resource" uid="uid://5yn4t13kwwoo" path="res://Cards/Resource/Card_DamageHealth.tres" id="5_j13b3"]
[ext_resource type="Resource" uid="uid://d4lugn62mmlep" path="res://Cards/Resource/Card_DrawCards.tres" id="6_4i4gj"]
[ext_resource type="Resource" uid="uid://ctx8jsvac84so" path="res://Cards/Resource/Card_Poison.tres" id="8_cs735"]
[ext_resource type="Resource" uid="uid://dxgoopi1roxu4" path="res://Cards/Resource/Card_Damage.tres" id="4_wvn3v"]
[ext_resource type="Resource" uid="uid://0x385c3nuq8f" path="res://Cards/Resource/Card_DamageAll.tres" id="5_j1lqt"]
[ext_resource type="Resource" uid="uid://5yn4t13kwwoo" path="res://Cards/Resource/Card_DamageHealth.tres" id="6_4124l"]
[ext_resource type="Resource" uid="uid://d4lugn62mmlep" path="res://Cards/Resource/Card_DrawCards.tres" id="7_smkw8"]
[ext_resource type="PackedScene" uid="uid://bcpmrmofcilbn" path="res://Core/Battler.tscn" id="8_qtw1k"]
[ext_resource type="Resource" uid="uid://3s4aet1ciesh" path="res://Cards/Resource/Card_damage_and_poison.tres" id="8_ruc8h"]
[ext_resource type="Script" path="res://UI/DrawPileUISetter.gd" id="8_voref"]
[ext_resource type="Resource" uid="uid://ctx8jsvac84so" path="res://Cards/Resource/Card_Poison.tres" id="8_x6t2k"]
[ext_resource type="Resource" uid="uid://d12g33rc6c3u5" path="res://Cards/Resource/Card_Heal.tres" id="9_ojxic"]
[ext_resource type="Script" path="res://UI/DiscardPileUISetter.gd" id="10_pqly7"]
[ext_resource type="Resource" uid="uid://3s4aet1ciesh" path="res://Cards/Resource/Card_damage_and_poison.tres" id="10_w0xgm"]
[ext_resource type="Resource" uid="uid://bsrdu33ukb1ym" path="res://Cards/Resource/Card_EnemyAttack.tres" id="11_3k5t2"]
[ext_resource type="Texture2D" uid="uid://caemucaya30wh" path="res://Cards/draw_pile.png" id="11_pw70x"]
[ext_resource type="Texture2D" uid="uid://d4muqvs3etnr8" path="res://Cards/discard_pile.png" id="12_kxw48"]
[ext_resource type="Script" path="res://UI/EndTurnButton.gd" id="14_dpe64"]
Expand All @@ -21,9 +24,6 @@
[node name="Player" parent="." instance=ExtResource("3_4psp7")]
position = Vector2(595, 284)

[node name="CardContainer" parent="." instance=ExtResource("3_e7sws")]
default_deck = Array[Resource("res://Cards/CardBase.gd")]([ExtResource("4_uiqnj"), ExtResource("5_j13b3"), ExtResource("6_4i4gj"), ExtResource("8_cs735"), ExtResource("8_ruc8h")])

[node name="CanvasLayer" type="CanvasLayer" parent="."]

[node name="UIControl" type="Control" parent="CanvasLayer"]
Expand All @@ -35,6 +35,25 @@ grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2

[node name="CardContainer" parent="CanvasLayer/UIControl" node_paths=PackedStringArray("draw_pile_ui", "discard_pile_ui") instance=ExtResource("3_e7sws")]
layout_mode = 1
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 0
default_deck = Array[Resource("res://Cards/CardBase.gd")]([ExtResource("4_wvn3v"), ExtResource("5_j1lqt"), ExtResource("6_4124l"), ExtResource("7_smkw8"), ExtResource("9_ojxic"), ExtResource("8_x6t2k"), ExtResource("10_w0xgm"), ExtResource("11_3k5t2")])
starting_hand_size = 10
max_hand_width = 900.0
min_card_separation = 90.0
max_card_separation = 120.0
hover_offset_max = 100.0
max_rotation = 40.0
draw_pile_ui = NodePath("../DrawPile")
discard_pile_ui = NodePath("../DiscardPile")

[node name="EndTurnButton" type="Button" parent="CanvasLayer/UIControl"]
layout_mode = 1
anchors_preset = 3
Expand Down
15 changes: 8 additions & 7 deletions Cards/Card.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,26 @@
[ext_resource type="Script" path="res://Cards/CardWorld.gd" id="1_4el5m"]
[ext_resource type="Texture2D" uid="uid://nheutko3fha3" path="res://Cards/card.png" id="2_k6rq5"]
[ext_resource type="Script" path="res://Input/ClickHandler.gd" id="3_du4nn"]
[ext_resource type="Script" path="res://Helpers/LerpComponent.gd" id="4_ujyje"]
[ext_resource type="Script" path="res://UI/CardUISetter.gd" id="5_hkyxd"]
[ext_resource type="Texture2D" uid="uid://bdc5r0w6lyh34" path="res://Cards/card_image.png" id="6_p357x"]
[ext_resource type="Script" path="res://Cards/CardMovementComponent.gd" id="6_qvt2l"]

[sub_resource type="LabelSettings" id="LabelSettings_ooxvf"]
font_color = Color(0, 0, 0, 1)

[node name="Card" type="Node2D"]
[node name="Card" type="Control"]
layout_mode = 3
anchors_preset = 0
script = ExtResource("1_4el5m")

[node name="ClickHandler" type="Node2D" parent="."]
[node name="ClickHandler" type="Node" parent="."]
script = ExtResource("3_du4nn")

[node name="LerpComponent" type="Node2D" parent="."]
script = ExtResource("4_ujyje")
lerp_speed = 7.0
[node name="CardMovementComponent" type="Node" parent="."]
script = ExtResource("6_qvt2l")

[node name="CardUI" type="Control" parent="." node_paths=PackedStringArray("title_label", "description_label", "key_art")]
layout_mode = 3
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
Expand Down
72 changes: 68 additions & 4 deletions Cards/CardBase.gd
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@ class_name CardBase
## wish to take damage in some contexts.
## For example, consider the card: "Deal 10 damage to all enemies, but take 3 damage"


# @export var status_to_apply_to_target: Array[StatusBase]
# @export var status_to_apply_to_caster: Array[StatusBase]
@export var damage_to_apply_to_target: float = 0.0
@export var damage_to_apply_to_caster: float = 0.0
@export var status_to_apply_to_target: Array[StatusBase]
@export var status_to_apply_to_caster: Array[StatusBase]
@export var affect_all_targets: bool = false
@export var affect_all_casters: bool = false
@export var amount_of_cards_to_draw: int = 0
@export var amount_of_cards_to_discard: int = 0
@export var application_type: Enums.ApplicationType = Enums.ApplicationType.ENEMY_ONLY
@export var card_title: String = "NULL"
@export var card_key_art: ImageTexture = null
Expand Down Expand Up @@ -43,5 +48,64 @@ func can_play_card(caster: Entity, target: Entity) -> bool:
return caster.get_party_component().can_play_on_entity(application_type, target)


func on_card_play(target: Entity) -> void:
func on_card_play(caster: Entity, target: Entity) -> void:
_apply_all_effects(target)
_deal_damage(caster, target)
_apply_status(caster, target)
_draw_cards()
_discard_random_cards()
CardManager.on_card_action_finished.emit(self)
# TODO add other functionality that lots of cards may share (eg: restore AP)


# override in child cards if you want to deal damage in a unique way
func _deal_damage(caster: Entity, target: Entity) -> void:
# damage target
if damage_to_apply_to_target != 0.0:
_damage_entity(caster, target, damage_to_apply_to_target, affect_all_targets)

#damage caster
if damage_to_apply_to_caster != 0.0:
_damage_entity(caster, caster, damage_to_apply_to_caster, affect_all_casters)


func _damage_entity(caster: Entity, target: Entity, damage_amount: float, damage_all: bool) -> void:
var target_damage_data: DealDamageData = DealDamageData.new()
target_damage_data.damage = damage_amount
target_damage_data.caster = caster

# If damage_all is set, try to damage all the party members set in the party component
if damage_all:
var party: Array[Entity] = target.get_party_component().party
assert(party.size() > 0, "Entity has an empty party. Make sure you added party members.")

for party_member: Entity in party:
party_member.get_health_component().deal_damage(target_damage_data)
else:
target.get_health_component().deal_damage(target_damage_data)


func _apply_status(caster: Entity, target: Entity) -> void:
# apply status to caster
for status: StatusBase in status_to_apply_to_caster:
if affect_all_casters:
for party_member: Entity in caster.get_party_component().party:
party_member.get_status_component().add_status(status, caster)
else:
caster.get_status_component().add_status(status, caster)

# apply status to target
for status: StatusBase in status_to_apply_to_target:
if affect_all_targets:
for party_member: Entity in target.get_party_component().party:
party_member.get_status_component().add_status(status, caster)
else:
target.get_status_component().add_status(status, caster)


func _draw_cards() -> void:
CardManager.card_container.draw_cards(amount_of_cards_to_draw)


func _discard_random_cards() -> void:
CardManager.card_container.discard_random_card(amount_of_cards_to_discard)
Loading

0 comments on commit f0803c5

Please sign in to comment.