From dd0c7a6058a13a3b4c4de5e3ee0b000a1144aebb Mon Sep 17 00:00:00 2001 From: Tyson Decker Date: Thu, 21 Aug 2025 18:02:02 -0600 Subject: [PATCH 1/5] added drag strategy and start refactoring examples to use it --- addons/card_3d/scenes/card_collection_3d.tscn | 2 +- .../card_collection_3d.gd | 22 +-- .../card_collection_3d.gd.uid | 0 .../scripts/card_collection/drag_strategy.gd | 41 +++++ .../card_collection/drag_strategy.gd.uid | 1 + example_battle/scenes/battle.gd | 2 +- example_battle/scenes/battle.tscn | 15 +- example_battle/scripts/play_card_dropzone.gd | 10 +- example_solitaire/scenes/solitaire.gd | 4 +- example_solitaire/scenes/solitaire.tscn | 151 ++++++++++++------ example_solitaire/scripts/card_column.gd | 18 ++- 11 files changed, 182 insertions(+), 84 deletions(-) rename addons/card_3d/scripts/{ => card_collection}/card_collection_3d.gd (93%) rename addons/card_3d/scripts/{ => card_collection}/card_collection_3d.gd.uid (100%) create mode 100644 addons/card_3d/scripts/card_collection/drag_strategy.gd create mode 100644 addons/card_3d/scripts/card_collection/drag_strategy.gd.uid diff --git a/addons/card_3d/scenes/card_collection_3d.tscn b/addons/card_3d/scenes/card_collection_3d.tscn index 03731ae..b1c4ba4 100644 --- a/addons/card_3d/scenes/card_collection_3d.tscn +++ b/addons/card_3d/scenes/card_collection_3d.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=3 uid="uid://d1uvcisduvvj"] -[ext_resource type="Script" uid="uid://bhsbphug3lcqi" path="res://addons/card_3d/scripts/card_collection_3d.gd" id="1_0ckh6"] +[ext_resource type="Script" uid="uid://bhsbphug3lcqi" path="res://addons/card_3d/scripts/card_collection/card_collection_3d.gd" id="1_0ckh6"] [ext_resource type="Script" uid="uid://jkfm6q5w8u83" path="res://addons/card_3d/scripts/card_collection/drop_zone_editor_tool.gd" id="2_l4h6k"] [ext_resource type="Shape3D" uid="uid://cicwtlugivwj4" path="res://addons/card_3d/shapes_3d/default_card_collection_3d_drop_zone_shape_3d.tres" id="2_xh0md"] diff --git a/addons/card_3d/scripts/card_collection_3d.gd b/addons/card_3d/scripts/card_collection/card_collection_3d.gd similarity index 93% rename from addons/card_3d/scripts/card_collection_3d.gd rename to addons/card_3d/scripts/card_collection/card_collection_3d.gd index 8fea04e..b9f42b7 100644 --- a/addons/card_3d/scripts/card_collection_3d.gd +++ b/addons/card_3d/scripts/card_collection/card_collection_3d.gd @@ -34,6 +34,9 @@ const _DEFAULT_DROP_ZONE_Z_OFFSET: float = 1.6 set(strategy): card_layout_strategy = strategy apply_card_layout() +@export var drag_strategy: DragStrategy = DragStrategy.new(): + set(strategy): + drag_strategy = strategy if strategy else DragStrategy.new() @export var dropzone_collision_shape: Shape3D = null: set(v): $DropZone/CollisionShape3D.shape = v if v else _DEFAULT_DROP_ZONE_SHAPE_3D @@ -234,19 +237,18 @@ func _on_drop_zone_mouse_exited(): _preview_drop_index = -1 mouse_exit_drop_zone.emit() -# whether or not a card can be selected -func can_select_card(_card) -> bool: - return true + +func can_select_card(card) -> bool: + return drag_strategy.can_select_card(card, self) -func can_remove_card(_card) -> bool: - return true +func can_remove_card(card) -> bool: + return drag_strategy.can_remove_card(card, self) -func can_reorder_card(_card) -> bool: - return true +func can_reorder_card(card) -> bool: + return drag_strategy.can_reorder_card(card, self) -# if the card can be inserted to the collection -func can_insert_card(_card, _from_collection) -> bool: - return true +func can_insert_card(card, from_collection) -> bool: + return drag_strategy.can_insert_card(card, self, from_collection) diff --git a/addons/card_3d/scripts/card_collection_3d.gd.uid b/addons/card_3d/scripts/card_collection/card_collection_3d.gd.uid similarity index 100% rename from addons/card_3d/scripts/card_collection_3d.gd.uid rename to addons/card_3d/scripts/card_collection/card_collection_3d.gd.uid diff --git a/addons/card_3d/scripts/card_collection/drag_strategy.gd b/addons/card_3d/scripts/card_collection/drag_strategy.gd new file mode 100644 index 0000000..f3869a9 --- /dev/null +++ b/addons/card_3d/scripts/card_collection/drag_strategy.gd @@ -0,0 +1,41 @@ +class_name DragStrategy +extends Resource +""" +DragStrategy +====================== + +This module defines an interface that describes how cards can drag from different collections. +It can be configured either by: + 1. setting the drag stragegy on your collection to "NewDragStrategy" via the resource menu in + node the inspector and changing the default boolean values + 2. creating a custom script that extends DragStrategy and overriding + (can_select_card, can_remove_card, can_reorder_card, can_insert_card) + to describe checks conditional to the card and collection +""" + + +@export_group("Default Behavior") +@export var can_select: bool = true +@export var can_remove: bool = true +@export var can_reorder: bool = true +@export var can_insert: bool = true + + +func can_select_card(_card, to_collection: CardCollection3D) -> bool: + return can_select + + +func can_remove_card(_card, _to_collection: CardCollection3D) -> bool: + return can_remove + + +func can_reorder_card(_card, _to_collection: CardCollection3D) -> bool: + return can_reorder + + +func can_insert_card( + _card, + _to_collection: CardCollection3D, + _from_collection: CardCollection3D + ) -> bool: + return can_insert diff --git a/addons/card_3d/scripts/card_collection/drag_strategy.gd.uid b/addons/card_3d/scripts/card_collection/drag_strategy.gd.uid new file mode 100644 index 0000000..b0863ec --- /dev/null +++ b/addons/card_3d/scripts/card_collection/drag_strategy.gd.uid @@ -0,0 +1 @@ +uid://drpbrbrd8kfxn diff --git a/example_battle/scenes/battle.gd b/example_battle/scenes/battle.gd index 0831384..ab1fd5b 100644 --- a/example_battle/scenes/battle.gd +++ b/example_battle/scenes/battle.gd @@ -35,5 +35,5 @@ func _on_play_zone_card_added(card: BattleCard3D): card.queue_free() monster.health -= card.damage if monster.health <= 0: - $DragController/PlayZone.play_enabled = false + $DragController/PlayZone.drag_strategy.play_enabled = false monster.queue_free() diff --git a/example_battle/scenes/battle.tscn b/example_battle/scenes/battle.tscn index 6678c33..839f4e3 100644 --- a/example_battle/scenes/battle.tscn +++ b/example_battle/scenes/battle.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=10 format=3 uid="uid://fdx3muhixky4"] +[gd_scene load_steps=11 format=3 uid="uid://fdx3muhixky4"] [ext_resource type="Script" uid="uid://bwet1jv3qfdxg" path="res://example_battle/scenes/battle.gd" id="1_wmhlq"] [ext_resource type="PackedScene" uid="uid://d1uvcisduvvj" path="res://addons/card_3d/scenes/card_collection_3d.tscn" id="2_6x4v1"] @@ -13,6 +13,15 @@ size = Vector2(50, 50) [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_s1erc"] albedo_color = Color(0.207843, 0.396078, 0.301961, 1) +[sub_resource type="Resource" id="Resource_q3f0o"] +script = ExtResource("4_d6qeg") +play_enabled = true +can_select = true +can_remove = true +can_reorder = true +can_insert = true +metadata/_custom_type_script = "uid://blba82h7r8vut" + [sub_resource type="Resource" id="Resource_eexvo"] script = ExtResource("3_0udwp") direction = 0 @@ -43,9 +52,7 @@ card_drag_plane = Plane(0, 0, 1, 4) [node name="PlayZone" parent="DragController" instance=ExtResource("2_6x4v1")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.309844) -script = ExtResource("4_d6qeg") -play_enabled = true -highlight_on_hover = false +drag_strategy = SubResource("Resource_q3f0o") [node name="CardCollection3D" parent="DragController" instance=ExtResource("2_6x4v1")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -3.39072, 0) diff --git a/example_battle/scripts/play_card_dropzone.gd b/example_battle/scripts/play_card_dropzone.gd index 2d5195e..e819706 100644 --- a/example_battle/scripts/play_card_dropzone.gd +++ b/example_battle/scripts/play_card_dropzone.gd @@ -1,21 +1,21 @@ class_name PlayCardDropzone -extends CardCollection3D +extends DragStrategy @export var play_enabled: bool = true -func can_insert_card(_card: BattleCard3D, _from_collection) -> bool: +func can_insert_card(_card: BattleCard3D, _to_collection, _from_collection) -> bool: return play_enabled -func can_reorder_card(_card: BattleCard3D) -> bool: +func can_reorder_card(_card: BattleCard3D, _collection) -> bool: return false -func can_select_card(_card: BattleCard3D) -> bool: +func can_select_card(_card: BattleCard3D, _collection) -> bool: return false -func can_remove_card(_card: BattleCard3D) -> bool: +func can_remove_card(_card: BattleCard3D, _collection) -> bool: return false diff --git a/example_solitaire/scenes/solitaire.gd b/example_solitaire/scenes/solitaire.gd index e190b1f..f35b044 100644 --- a/example_solitaire/scenes/solitaire.gd +++ b/example_solitaire/scenes/solitaire.gd @@ -99,8 +99,8 @@ func _on_drag_controller_card_moved(_card: FaceCard3D, from_collection: CardColl if from_collection == to_collection: return - if not from_collection is CardColumn or not to_collection is CardColumn: - return + #if not from_collection is CardColumn or not to_collection is CardColumn: + #return while from_collection.cards.size() > from_index: var new_position = from_collection.cards[from_index].global_position diff --git a/example_solitaire/scenes/solitaire.tscn b/example_solitaire/scenes/solitaire.tscn index 45a82e2..b986ccb 100644 --- a/example_solitaire/scenes/solitaire.tscn +++ b/example_solitaire/scenes/solitaire.tscn @@ -1,16 +1,15 @@ -[gd_scene load_steps=32 format=3 uid="uid://b3nx7g0iu2cd3"] +[gd_scene load_steps=38 format=3 uid="uid://b3nx7g0iu2cd3"] [ext_resource type="Script" uid="uid://btwpxkyhem6kk" path="res://example_solitaire/scenes/solitaire.gd" id="1_vfkpr"] [ext_resource type="Script" uid="uid://bgkontnk0cnl" path="res://addons/card_3d/scripts/drag_controller.gd" id="2_evxo0"] [ext_resource type="PackedScene" uid="uid://d1uvcisduvvj" path="res://addons/card_3d/scenes/card_collection_3d.tscn" id="3_kmjqy"] -[ext_resource type="Script" uid="uid://ciacu28a6jpj6" path="res://example_solitaire/scripts/draw_pile.gd" id="4_mvhgr"] +[ext_resource type="Script" uid="uid://0178mh1k53xw" path="res://example_solitaire/scripts/draw_pile.gd" id="4_mvhgr"] [ext_resource type="Script" uid="uid://dsyors6p1ph7" path="res://addons/card_3d/scripts/card_layouts/pile_card_layout.gd" id="4_ykggm"] [ext_resource type="Script" uid="uid://c4eh7en1au78a" path="res://example_solitaire/scripts/card_column.gd" id="5_j26y4"] [ext_resource type="Script" uid="uid://crx78y6320odd" path="res://example_solitaire/scripts/suit_discard.gd" id="5_vnftc"] [ext_resource type="Script" uid="uid://cpcw405f10750" path="res://example_solitaire/scripts/stack_layout.gd" id="5_y307u"] -[ext_resource type="Shape3D" uid="uid://b4ul43sikpt87" path="res://example_solitaire/column_collision.tres" id="8_bfwbd"] +[ext_resource type="Script" uid="uid://drpbrbrd8kfxn" path="res://addons/card_3d/scripts/card_collection/drag_strategy.gd" id="9_xhcv4"] [ext_resource type="PackedScene" uid="uid://cviptf2wh1pc0" path="res://example_solitaire/scenes/pile_marker.tscn" id="9_xrvyx"] -[ext_resource type="Script" uid="uid://ctgydx6cirejo" path="res://example_solitaire/scripts/deck.gd" id="10_0hsa4"] [sub_resource type="BoxMesh" id="BoxMesh_3x48k"] size = Vector3(50, 30, 0.1) @@ -50,40 +49,109 @@ pile_y_offset = 0.0 [sub_resource type="BoxShape3D" id="BoxShape3D_rescc"] size = Vector3(3, 4, 0.5) -[sub_resource type="Resource" id="Resource_pprhl"] +[sub_resource type="Resource" id="Resource_x8i2t"] script = ExtResource("5_y307u") distance = 0.8 +metadata/_custom_type_script = "uid://cpcw405f10750" -[sub_resource type="Resource" id="Resource_xa5h1"] +[sub_resource type="Resource" id="Resource_jw1jw"] +script = ExtResource("5_j26y4") +can_select = true +can_remove = true +can_reorder = true +can_insert = true +metadata/_custom_type_script = "uid://c4eh7en1au78a" + +[sub_resource type="Resource" id="Resource_q5e5c"] script = ExtResource("5_y307u") distance = 0.8 +metadata/_custom_type_script = "uid://cpcw405f10750" -[sub_resource type="Resource" id="Resource_nx85c"] +[sub_resource type="Resource" id="Resource_xhcv4"] +script = ExtResource("5_j26y4") +can_select = true +can_remove = true +can_reorder = true +can_insert = true +metadata/_custom_type_script = "uid://c4eh7en1au78a" + +[sub_resource type="Resource" id="Resource_xy1l5"] script = ExtResource("5_y307u") distance = 0.8 +metadata/_custom_type_script = "uid://cpcw405f10750" -[sub_resource type="Resource" id="Resource_vr3hi"] +[sub_resource type="Resource" id="Resource_w66lm"] +script = ExtResource("5_j26y4") +can_select = true +can_remove = true +can_reorder = true +can_insert = true +metadata/_custom_type_script = "uid://c4eh7en1au78a" + +[sub_resource type="Resource" id="Resource_tu0lf"] script = ExtResource("5_y307u") distance = 0.8 +metadata/_custom_type_script = "uid://cpcw405f10750" + +[sub_resource type="Resource" id="Resource_qw2g7"] +script = ExtResource("5_j26y4") +can_select = true +can_remove = true +can_reorder = true +can_insert = true +metadata/_custom_type_script = "uid://c4eh7en1au78a" -[sub_resource type="Resource" id="Resource_i28x6"] +[sub_resource type="Resource" id="Resource_eya50"] script = ExtResource("5_y307u") distance = 0.8 +metadata/_custom_type_script = "uid://cpcw405f10750" + +[sub_resource type="Resource" id="Resource_5orty"] +script = ExtResource("5_j26y4") +can_select = true +can_remove = true +can_reorder = true +can_insert = true +metadata/_custom_type_script = "uid://c4eh7en1au78a" -[sub_resource type="Resource" id="Resource_10me3"] +[sub_resource type="Resource" id="Resource_wxkx0"] script = ExtResource("5_y307u") distance = 0.8 +metadata/_custom_type_script = "uid://cpcw405f10750" + +[sub_resource type="Resource" id="Resource_awgux"] +script = ExtResource("5_j26y4") +can_select = true +can_remove = true +can_reorder = true +can_insert = true +metadata/_custom_type_script = "uid://c4eh7en1au78a" -[sub_resource type="Resource" id="Resource_inowq"] +[sub_resource type="Resource" id="Resource_mimnj"] script = ExtResource("5_y307u") distance = 0.8 +metadata/_custom_type_script = "uid://cpcw405f10750" + +[sub_resource type="Resource" id="Resource_23sxf"] +script = ExtResource("5_j26y4") +can_select = true +can_remove = true +can_reorder = true +can_insert = true +metadata/_custom_type_script = "uid://c4eh7en1au78a" -[sub_resource type="Resource" id="Resource_4ui3d"] +[sub_resource type="Resource" id="Resource_bpv8x"] script = ExtResource("4_ykggm") pile_y_offset = 0.0 +metadata/_custom_type_script = "uid://dsyors6p1ph7" -[sub_resource type="BoxShape3D" id="BoxShape3D_iid3l"] -size = Vector3(2.5, 3.5, 2) +[sub_resource type="Resource" id="Resource_n03b6"] +script = ExtResource("9_xhcv4") +can_select = false +can_remove = false +can_reorder = false +can_insert = false +metadata/_custom_type_script = "uid://drpbrbrd8kfxn" [node name="Solitaire" type="Node3D"] script = ExtResource("1_vfkpr") @@ -142,66 +210,43 @@ dropzone_z_offset = 0.0 [node name="Column1" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15, 0, 0) -script = ExtResource("5_j26y4") -highlight_on_hover = false -card_layout_strategy = SubResource("Resource_pprhl") -dropzone_collision_shape = ExtResource("8_bfwbd") -dropzone_z_offset = 0.0 +card_layout_strategy = SubResource("Resource_x8i2t") +drag_strategy = SubResource("Resource_jw1jw") [node name="Column2" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11, 0, 0) -script = ExtResource("5_j26y4") -highlight_on_hover = false -card_layout_strategy = SubResource("Resource_xa5h1") -dropzone_collision_shape = ExtResource("8_bfwbd") -dropzone_z_offset = 0.0 +card_layout_strategy = SubResource("Resource_q5e5c") +drag_strategy = SubResource("Resource_xhcv4") [node name="Column3" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7, 0, 0) -script = ExtResource("5_j26y4") -highlight_on_hover = false -card_layout_strategy = SubResource("Resource_nx85c") -dropzone_collision_shape = ExtResource("8_bfwbd") -dropzone_z_offset = 0.0 +card_layout_strategy = SubResource("Resource_xy1l5") +drag_strategy = SubResource("Resource_w66lm") [node name="Column4" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, 0) -script = ExtResource("5_j26y4") -highlight_on_hover = false -card_layout_strategy = SubResource("Resource_vr3hi") -dropzone_collision_shape = ExtResource("8_bfwbd") -dropzone_z_offset = 0.0 +card_layout_strategy = SubResource("Resource_tu0lf") +drag_strategy = SubResource("Resource_qw2g7") [node name="Column5" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0) -script = ExtResource("5_j26y4") -highlight_on_hover = false -card_layout_strategy = SubResource("Resource_i28x6") -dropzone_collision_shape = ExtResource("8_bfwbd") -dropzone_z_offset = 0.0 +card_layout_strategy = SubResource("Resource_eya50") +drag_strategy = SubResource("Resource_5orty") [node name="Column6" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5, 0, 0) -script = ExtResource("5_j26y4") -highlight_on_hover = false -card_layout_strategy = SubResource("Resource_10me3") -dropzone_collision_shape = ExtResource("8_bfwbd") -dropzone_z_offset = 0.0 +card_layout_strategy = SubResource("Resource_wxkx0") +drag_strategy = SubResource("Resource_awgux") [node name="Column7" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9, 0, 0) -script = ExtResource("5_j26y4") -highlight_on_hover = false -card_layout_strategy = SubResource("Resource_inowq") -dropzone_collision_shape = ExtResource("8_bfwbd") -dropzone_z_offset = 0.0 +card_layout_strategy = SubResource("Resource_mimnj") +drag_strategy = SubResource("Resource_23sxf") [node name="Deck" parent="." instance=ExtResource("3_kmjqy")] transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, -15, 7, 0) -script = ExtResource("10_0hsa4") -highlight_on_hover = false -card_layout_strategy = SubResource("Resource_4ui3d") -dropzone_collision_shape = SubResource("BoxShape3D_iid3l") +card_layout_strategy = SubResource("Resource_bpv8x") +drag_strategy = SubResource("Resource_n03b6") [node name="EmptyDeck" parent="." instance=ExtResource("9_xrvyx")] visible = false diff --git a/example_solitaire/scripts/card_column.gd b/example_solitaire/scripts/card_column.gd index 773fb7f..e90015c 100644 --- a/example_solitaire/scripts/card_column.gd +++ b/example_solitaire/scripts/card_column.gd @@ -1,13 +1,15 @@ -class_name CardColumn -extends CardCollection3D +class_name CardColumnDragStrategy +extends DragStrategy -func can_insert_card(card: FaceCard3D, _from_collection) -> bool: +func can_insert_card(card: FaceCard3D, to_collection, _from_collection) -> bool: + var cards = to_collection.cards + if cards.size() == 0: return true var last_card = cards[cards.size() - 1] var is_prior_rank = card.rank == last_card.rank - 1 - var is_opposite_color = false; + var is_opposite_color = false if (card.suit == FaceCards.Suit.HEART or card.suit == FaceCards.Suit.DIAMOND) and \ (last_card.suit == FaceCards.Suit.CLUB or last_card.suit == FaceCards.Suit.SPADE): @@ -19,11 +21,11 @@ func can_insert_card(card: FaceCard3D, _from_collection) -> bool: return last_card.face_down or (is_opposite_color and is_prior_rank) -func can_reorder_card(_card: FaceCard3D) -> bool: +func can_reorder_card(_card: FaceCard3D, collection: CardCollection3D) -> bool: return false -func can_select_card(card: FaceCard3D) -> bool: - var card_index = card_indicies[card] +func can_select_card(card: FaceCard3D, collection: CardCollection3D) -> bool: + var card_index = collection.card_indicies[card] - return !card.face_down or card_index == (cards.size() - 1) + return !card.face_down or card_index == (collection.cards.size() - 1) From b58a275a1b2dfac3ad8e0eb0ab5ce51b95194dae Mon Sep 17 00:00:00 2001 From: Tyson Decker Date: Thu, 21 Aug 2025 18:29:07 -0600 Subject: [PATCH 2/5] finish fixing solitaire example to use drag strategy --- example_solitaire/scenes/solitaire.gd | 3 - example_solitaire/scenes/solitaire.tscn | 122 +++++++++++++----- example_solitaire/scripts/deck.gd | 17 --- example_solitaire/scripts/deck.gd.uid | 1 - example_solitaire/scripts/draw_pile.gd | 17 --- example_solitaire/scripts/draw_pile.gd.uid | 1 - example_solitaire/scripts/suit_discard.gd | 20 +-- .../{ => shapes}/column_collision.tres | 0 .../shapes/discard_collision.tres | 4 + 9 files changed, 97 insertions(+), 88 deletions(-) delete mode 100644 example_solitaire/scripts/deck.gd delete mode 100644 example_solitaire/scripts/deck.gd.uid delete mode 100644 example_solitaire/scripts/draw_pile.gd delete mode 100644 example_solitaire/scripts/draw_pile.gd.uid rename example_solitaire/{ => shapes}/column_collision.tres (100%) create mode 100644 example_solitaire/shapes/discard_collision.tres diff --git a/example_solitaire/scenes/solitaire.gd b/example_solitaire/scenes/solitaire.gd index f35b044..61c7171 100644 --- a/example_solitaire/scenes/solitaire.gd +++ b/example_solitaire/scenes/solitaire.gd @@ -99,9 +99,6 @@ func _on_drag_controller_card_moved(_card: FaceCard3D, from_collection: CardColl if from_collection == to_collection: return - #if not from_collection is CardColumn or not to_collection is CardColumn: - #return - while from_collection.cards.size() > from_index: var new_position = from_collection.cards[from_index].global_position var card = from_collection.remove_card(from_index) diff --git a/example_solitaire/scenes/solitaire.tscn b/example_solitaire/scenes/solitaire.tscn index b986ccb..c3fe79c 100644 --- a/example_solitaire/scenes/solitaire.tscn +++ b/example_solitaire/scenes/solitaire.tscn @@ -1,13 +1,14 @@ -[gd_scene load_steps=38 format=3 uid="uid://b3nx7g0iu2cd3"] +[gd_scene load_steps=40 format=3 uid="uid://b3nx7g0iu2cd3"] [ext_resource type="Script" uid="uid://btwpxkyhem6kk" path="res://example_solitaire/scenes/solitaire.gd" id="1_vfkpr"] [ext_resource type="Script" uid="uid://bgkontnk0cnl" path="res://addons/card_3d/scripts/drag_controller.gd" id="2_evxo0"] [ext_resource type="PackedScene" uid="uid://d1uvcisduvvj" path="res://addons/card_3d/scenes/card_collection_3d.tscn" id="3_kmjqy"] -[ext_resource type="Script" uid="uid://0178mh1k53xw" path="res://example_solitaire/scripts/draw_pile.gd" id="4_mvhgr"] [ext_resource type="Script" uid="uid://dsyors6p1ph7" path="res://addons/card_3d/scripts/card_layouts/pile_card_layout.gd" id="4_ykggm"] [ext_resource type="Script" uid="uid://c4eh7en1au78a" path="res://example_solitaire/scripts/card_column.gd" id="5_j26y4"] [ext_resource type="Script" uid="uid://crx78y6320odd" path="res://example_solitaire/scripts/suit_discard.gd" id="5_vnftc"] [ext_resource type="Script" uid="uid://cpcw405f10750" path="res://example_solitaire/scripts/stack_layout.gd" id="5_y307u"] +[ext_resource type="Shape3D" uid="uid://b2q35fk3mga4d" path="res://example_solitaire/shapes/discard_collision.tres" id="7_w66lm"] +[ext_resource type="Shape3D" uid="uid://b4ul43sikpt87" path="res://example_solitaire/shapes/column_collision.tres" id="9_w66lm"] [ext_resource type="Script" uid="uid://drpbrbrd8kfxn" path="res://addons/card_3d/scripts/card_collection/drag_strategy.gd" id="9_xhcv4"] [ext_resource type="PackedScene" uid="uid://cviptf2wh1pc0" path="res://example_solitaire/scenes/pile_marker.tscn" id="9_xrvyx"] @@ -17,37 +18,70 @@ size = Vector3(50, 30, 0.1) [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_6u6h1"] albedo_color = Color(0.207843, 0.396078, 0.301961, 1) -[sub_resource type="Resource" id="Resource_vv0ke"] +[sub_resource type="Resource" id="Resource_6hsbc"] script = ExtResource("4_ykggm") pile_y_offset = 0.0 +metadata/_custom_type_script = "uid://dsyors6p1ph7" -[sub_resource type="Resource" id="Resource_mnku1"] +[sub_resource type="Resource" id="Resource_n03b6"] +script = ExtResource("9_xhcv4") +can_select = true +can_remove = true +can_reorder = false +can_insert = false +metadata/_custom_type_script = "uid://drpbrbrd8kfxn" + +[sub_resource type="Resource" id="Resource_ifhob"] script = ExtResource("4_ykggm") pile_y_offset = 0.0 +metadata/_custom_type_script = "uid://dsyors6p1ph7" -[sub_resource type="BoxShape3D" id="BoxShape3D_gk0xa"] -size = Vector3(3, 4, 0.5) +[sub_resource type="Resource" id="Resource_cl47x"] +script = ExtResource("5_vnftc") +can_select = false +can_remove = false +can_reorder = false +can_insert = true +metadata/_custom_type_script = "uid://crx78y6320odd" -[sub_resource type="Resource" id="Resource_tcgem"] +[sub_resource type="Resource" id="Resource_i4hcm"] script = ExtResource("4_ykggm") pile_y_offset = 0.0 +metadata/_custom_type_script = "uid://dsyors6p1ph7" -[sub_resource type="BoxShape3D" id="BoxShape3D_gmwdc"] -size = Vector3(3, 4, 0.5) +[sub_resource type="Resource" id="Resource_mrd3s"] +script = ExtResource("5_vnftc") +can_select = false +can_remove = false +can_reorder = false +can_insert = true +metadata/_custom_type_script = "uid://crx78y6320odd" -[sub_resource type="Resource" id="Resource_mqdnk"] +[sub_resource type="Resource" id="Resource_d026l"] script = ExtResource("4_ykggm") pile_y_offset = 0.0 +metadata/_custom_type_script = "uid://dsyors6p1ph7" -[sub_resource type="BoxShape3D" id="BoxShape3D_sqpmy"] -size = Vector3(3, 4, 0.5) +[sub_resource type="Resource" id="Resource_tpxco"] +script = ExtResource("5_vnftc") +can_select = false +can_remove = false +can_reorder = false +can_insert = true +metadata/_custom_type_script = "uid://crx78y6320odd" -[sub_resource type="Resource" id="Resource_686io"] +[sub_resource type="Resource" id="Resource_y6eo3"] script = ExtResource("4_ykggm") pile_y_offset = 0.0 +metadata/_custom_type_script = "uid://dsyors6p1ph7" -[sub_resource type="BoxShape3D" id="BoxShape3D_rescc"] -size = Vector3(3, 4, 0.5) +[sub_resource type="Resource" id="Resource_d1so3"] +script = ExtResource("5_vnftc") +can_select = false +can_remove = false +can_reorder = false +can_insert = true +metadata/_custom_type_script = "uid://crx78y6320odd" [sub_resource type="Resource" id="Resource_x8i2t"] script = ExtResource("5_y307u") @@ -145,10 +179,10 @@ script = ExtResource("4_ykggm") pile_y_offset = 0.0 metadata/_custom_type_script = "uid://dsyors6p1ph7" -[sub_resource type="Resource" id="Resource_n03b6"] +[sub_resource type="Resource" id="Resource_02cy2"] script = ExtResource("9_xhcv4") -can_select = false -can_remove = false +can_select = true +can_remove = true can_reorder = false can_insert = false metadata/_custom_type_script = "uid://drpbrbrd8kfxn" @@ -172,81 +206,103 @@ script = ExtResource("2_evxo0") [node name="Draw" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11, 7, 0) -script = ExtResource("4_mvhgr") highlight_on_hover = false -card_layout_strategy = SubResource("Resource_vv0ke") +card_layout_strategy = SubResource("Resource_6hsbc") +drag_strategy = SubResource("Resource_n03b6") [node name="SuitDiscard1" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 7, 0) -script = ExtResource("5_vnftc") highlight_on_hover = false -card_layout_strategy = SubResource("Resource_mnku1") -dropzone_collision_shape = SubResource("BoxShape3D_gk0xa") +card_layout_strategy = SubResource("Resource_ifhob") +drag_strategy = SubResource("Resource_cl47x") +dropzone_collision_shape = ExtResource("7_w66lm") dropzone_z_offset = 0.0 [node name="SuitDiscard2" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 7, 0) -script = ExtResource("5_vnftc") highlight_on_hover = false -card_layout_strategy = SubResource("Resource_tcgem") -dropzone_collision_shape = SubResource("BoxShape3D_gmwdc") +card_layout_strategy = SubResource("Resource_i4hcm") +drag_strategy = SubResource("Resource_mrd3s") +dropzone_collision_shape = ExtResource("7_w66lm") dropzone_z_offset = 0.0 [node name="SuitDiscard3" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5, 7, 0) -script = ExtResource("5_vnftc") highlight_on_hover = false -card_layout_strategy = SubResource("Resource_mqdnk") -dropzone_collision_shape = SubResource("BoxShape3D_sqpmy") +card_layout_strategy = SubResource("Resource_d026l") +drag_strategy = SubResource("Resource_tpxco") +dropzone_collision_shape = ExtResource("7_w66lm") dropzone_z_offset = 0.0 [node name="SuitDiscard4" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9, 7, 0) -script = ExtResource("5_vnftc") highlight_on_hover = false -card_layout_strategy = SubResource("Resource_686io") -dropzone_collision_shape = SubResource("BoxShape3D_rescc") +card_layout_strategy = SubResource("Resource_y6eo3") +drag_strategy = SubResource("Resource_d1so3") +dropzone_collision_shape = ExtResource("7_w66lm") dropzone_z_offset = 0.0 [node name="Column1" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15, 0, 0) +highlight_on_hover = false card_layout_strategy = SubResource("Resource_x8i2t") drag_strategy = SubResource("Resource_jw1jw") +dropzone_collision_shape = ExtResource("9_w66lm") +dropzone_z_offset = 0.0 [node name="Column2" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11, 0, 0) +highlight_on_hover = false card_layout_strategy = SubResource("Resource_q5e5c") drag_strategy = SubResource("Resource_xhcv4") +dropzone_collision_shape = ExtResource("9_w66lm") +dropzone_z_offset = 0.0 [node name="Column3" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7, 0, 0) +highlight_on_hover = false card_layout_strategy = SubResource("Resource_xy1l5") drag_strategy = SubResource("Resource_w66lm") +dropzone_collision_shape = ExtResource("9_w66lm") +dropzone_z_offset = 0.0 [node name="Column4" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, 0) +highlight_on_hover = false card_layout_strategy = SubResource("Resource_tu0lf") drag_strategy = SubResource("Resource_qw2g7") +dropzone_collision_shape = ExtResource("9_w66lm") +dropzone_z_offset = 0.0 [node name="Column5" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0) +highlight_on_hover = false card_layout_strategy = SubResource("Resource_eya50") drag_strategy = SubResource("Resource_5orty") +dropzone_collision_shape = ExtResource("9_w66lm") +dropzone_z_offset = 0.0 [node name="Column6" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5, 0, 0) +highlight_on_hover = false card_layout_strategy = SubResource("Resource_wxkx0") drag_strategy = SubResource("Resource_awgux") +dropzone_collision_shape = ExtResource("9_w66lm") +dropzone_z_offset = 0.0 [node name="Column7" parent="DragController" instance=ExtResource("3_kmjqy")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9, 0, 0) +highlight_on_hover = false card_layout_strategy = SubResource("Resource_mimnj") drag_strategy = SubResource("Resource_23sxf") +dropzone_collision_shape = ExtResource("9_w66lm") +dropzone_z_offset = 0.0 [node name="Deck" parent="." instance=ExtResource("3_kmjqy")] transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, -15, 7, 0) +highlight_on_hover = false card_layout_strategy = SubResource("Resource_bpv8x") -drag_strategy = SubResource("Resource_n03b6") +drag_strategy = SubResource("Resource_02cy2") [node name="EmptyDeck" parent="." instance=ExtResource("9_xrvyx")] visible = false diff --git a/example_solitaire/scripts/deck.gd b/example_solitaire/scripts/deck.gd deleted file mode 100644 index 805407c..0000000 --- a/example_solitaire/scripts/deck.gd +++ /dev/null @@ -1,17 +0,0 @@ -class_name Deck -extends CardCollection3D - -func can_insert_card(_card: FaceCard3D, _from_collection) -> bool: - return false - - -func can_reorder_card(_card: FaceCard3D) -> bool: - return false - - -func can_select_card(_card: FaceCard3D) -> bool: - return true - - -func can_remove_card(_card: FaceCard3D) -> bool: - return false diff --git a/example_solitaire/scripts/deck.gd.uid b/example_solitaire/scripts/deck.gd.uid deleted file mode 100644 index 32a88fd..0000000 --- a/example_solitaire/scripts/deck.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://ctgydx6cirejo diff --git a/example_solitaire/scripts/draw_pile.gd b/example_solitaire/scripts/draw_pile.gd deleted file mode 100644 index 527f5e7..0000000 --- a/example_solitaire/scripts/draw_pile.gd +++ /dev/null @@ -1,17 +0,0 @@ -class_name DrawPile -extends CardCollection3D - -func can_insert_card(_card: FaceCard3D, _from_collection) -> bool: - return false - - -func can_select_card(_card: FaceCard3D) -> bool: - return true - - -func can_reorder_card(_card: FaceCard3D) -> bool: - return false - - -func can_remove_card(_card: FaceCard3D) -> bool: - return true diff --git a/example_solitaire/scripts/draw_pile.gd.uid b/example_solitaire/scripts/draw_pile.gd.uid deleted file mode 100644 index 8322e58..0000000 --- a/example_solitaire/scripts/draw_pile.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://ciacu28a6jpj6 diff --git a/example_solitaire/scripts/suit_discard.gd b/example_solitaire/scripts/suit_discard.gd index 88db9db..1b41cac 100644 --- a/example_solitaire/scripts/suit_discard.gd +++ b/example_solitaire/scripts/suit_discard.gd @@ -1,27 +1,15 @@ class_name SuitDiscard -extends CardCollection3D +extends DragStrategy -func can_insert_card(card: FaceCard3D, from_collection: CardCollection3D) -> bool: +func can_insert_card(card: FaceCard3D, to_collection: CardCollection3D, from_collection: CardCollection3D) -> bool: if from_collection.card_indicies.has(card) and from_collection.card_indicies[card] < from_collection.cards.size() - 1: return false - if cards.size() == 0: + if to_collection.cards.size() == 0: return card.rank == FaceCards.Rank.ACE - var last_card = cards[cards.size() - 1] + var last_card = to_collection.cards[to_collection.cards.size() - 1] var is_next_rank = (card.rank == last_card.rank + 1) or (last_card.rank == FaceCards.Rank.ACE and card.rank == FaceCards.Rank.TWO) var is_same_suit = last_card.suit == card.suit return is_next_rank and is_same_suit - - -func can_reorder_card(_card: FaceCard3D) -> bool: - return false - - -func can_remove_card(_card: FaceCard3D) -> bool: - return false - - -func can_select_card(_card: FaceCard3D) -> bool: - return false diff --git a/example_solitaire/column_collision.tres b/example_solitaire/shapes/column_collision.tres similarity index 100% rename from example_solitaire/column_collision.tres rename to example_solitaire/shapes/column_collision.tres diff --git a/example_solitaire/shapes/discard_collision.tres b/example_solitaire/shapes/discard_collision.tres new file mode 100644 index 0000000..5478505 --- /dev/null +++ b/example_solitaire/shapes/discard_collision.tres @@ -0,0 +1,4 @@ +[gd_resource type="BoxShape3D" format=3 uid="uid://b2q35fk3mga4d"] + +[resource] +size = Vector3(4, 7, 0.5) From 7df4f14487b4d8e432c2894e859c2177d9600543 Mon Sep 17 00:00:00 2001 From: Tyson Decker Date: Thu, 21 Aug 2025 18:48:28 -0600 Subject: [PATCH 3/5] fix lint --- addons/card_3d/scripts/card_collection/drag_strategy.gd | 2 +- example_solitaire/scripts/card_column.gd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/card_3d/scripts/card_collection/drag_strategy.gd b/addons/card_3d/scripts/card_collection/drag_strategy.gd index f3869a9..5f2ab9f 100644 --- a/addons/card_3d/scripts/card_collection/drag_strategy.gd +++ b/addons/card_3d/scripts/card_collection/drag_strategy.gd @@ -21,7 +21,7 @@ It can be configured either by: @export var can_insert: bool = true -func can_select_card(_card, to_collection: CardCollection3D) -> bool: +func can_select_card(_card, _to_collection: CardCollection3D) -> bool: return can_select diff --git a/example_solitaire/scripts/card_column.gd b/example_solitaire/scripts/card_column.gd index e90015c..31ee474 100644 --- a/example_solitaire/scripts/card_column.gd +++ b/example_solitaire/scripts/card_column.gd @@ -21,7 +21,7 @@ func can_insert_card(card: FaceCard3D, to_collection, _from_collection) -> bool: return last_card.face_down or (is_opposite_color and is_prior_rank) -func can_reorder_card(_card: FaceCard3D, collection: CardCollection3D) -> bool: +func can_reorder_card(_card: FaceCard3D, _collection: CardCollection3D) -> bool: return false From 03d42f0b125aab3b38114bc6d57bc21171806551 Mon Sep 17 00:00:00 2001 From: Tyson Decker Date: Fri, 22 Aug 2025 09:30:15 -0600 Subject: [PATCH 4/5] polish up by adding type annotations, fixing typos, and refactoring common drag strategies in the example to an external resource. --- .../card_collection/card_collection_3d.gd | 8 +- .../scripts/card_collection/drag_strategy.gd | 10 +- example_battle/scenes/battle.tscn | 5 +- example_battle/scripts/play_card_dropzone.gd | 18 +-- .../resources/card_column_drag_strategy.tres | 11 ++ .../resources/suit_discard_drag_strategy.tres | 11 ++ example_solitaire/scenes/solitaire.tscn | 116 +++--------------- example_solitaire/scripts/card_column.gd | 6 +- example_solitaire/scripts/suit_discard.gd | 5 +- .../shapes/discard_collision.tres | 1 + 10 files changed, 62 insertions(+), 129 deletions(-) create mode 100644 example_solitaire/resources/card_column_drag_strategy.tres create mode 100644 example_solitaire/resources/suit_discard_drag_strategy.tres diff --git a/addons/card_3d/scripts/card_collection/card_collection_3d.gd b/addons/card_3d/scripts/card_collection/card_collection_3d.gd index b9f42b7..20558cb 100644 --- a/addons/card_3d/scripts/card_collection/card_collection_3d.gd +++ b/addons/card_3d/scripts/card_collection/card_collection_3d.gd @@ -238,17 +238,17 @@ func _on_drop_zone_mouse_exited(): mouse_exit_drop_zone.emit() -func can_select_card(card) -> bool: +func can_select_card(card: Card3D) -> bool: return drag_strategy.can_select_card(card, self) -func can_remove_card(card) -> bool: +func can_remove_card(card: Card3D) -> bool: return drag_strategy.can_remove_card(card, self) -func can_reorder_card(card) -> bool: +func can_reorder_card(card: Card3D) -> bool: return drag_strategy.can_reorder_card(card, self) -func can_insert_card(card, from_collection) -> bool: +func can_insert_card(card: Card3D, from_collection: CardCollection3D) -> bool: return drag_strategy.can_insert_card(card, self, from_collection) diff --git a/addons/card_3d/scripts/card_collection/drag_strategy.gd b/addons/card_3d/scripts/card_collection/drag_strategy.gd index 5f2ab9f..902401d 100644 --- a/addons/card_3d/scripts/card_collection/drag_strategy.gd +++ b/addons/card_3d/scripts/card_collection/drag_strategy.gd @@ -6,11 +6,11 @@ DragStrategy This module defines an interface that describes how cards can drag from different collections. It can be configured either by: - 1. setting the drag stragegy on your collection to "NewDragStrategy" via the resource menu in - node the inspector and changing the default boolean values - 2. creating a custom script that extends DragStrategy and overriding - (can_select_card, can_remove_card, can_reorder_card, can_insert_card) - to describe checks conditional to the card and collection + 1. Setting the drag strategy on your collection to a new DragStrategy resource via the Inspector + (Add Resource → DragStrategy) and configuring the default boolean values. + 2. Creating a custom script that extends DragStrategy and overriding the hooks + (can_select_card, can_remove_card, can_reorder_card, can_insert_card) + to implement checks based on the card and collection. """ diff --git a/example_battle/scenes/battle.tscn b/example_battle/scenes/battle.tscn index 839f4e3..f6c417a 100644 --- a/example_battle/scenes/battle.tscn +++ b/example_battle/scenes/battle.tscn @@ -14,11 +14,12 @@ size = Vector2(50, 50) albedo_color = Color(0.207843, 0.396078, 0.301961, 1) [sub_resource type="Resource" id="Resource_q3f0o"] +resource_name = "PlayZoneDragStrategy" script = ExtResource("4_d6qeg") play_enabled = true can_select = true -can_remove = true -can_reorder = true +can_remove = false +can_reorder = false can_insert = true metadata/_custom_type_script = "uid://blba82h7r8vut" diff --git a/example_battle/scripts/play_card_dropzone.gd b/example_battle/scripts/play_card_dropzone.gd index e819706..b8773ed 100644 --- a/example_battle/scripts/play_card_dropzone.gd +++ b/example_battle/scripts/play_card_dropzone.gd @@ -5,17 +5,9 @@ extends DragStrategy @export var play_enabled: bool = true -func can_insert_card(_card: BattleCard3D, _to_collection, _from_collection) -> bool: +func can_insert_card( + _card: BattleCard3D, + _to_collection: CardCollection3D, + _from_collection: CardCollection3D + ) -> bool: return play_enabled - - -func can_reorder_card(_card: BattleCard3D, _collection) -> bool: - return false - - -func can_select_card(_card: BattleCard3D, _collection) -> bool: - return false - - -func can_remove_card(_card: BattleCard3D, _collection) -> bool: - return false diff --git a/example_solitaire/resources/card_column_drag_strategy.tres b/example_solitaire/resources/card_column_drag_strategy.tres new file mode 100644 index 0000000..6adac73 --- /dev/null +++ b/example_solitaire/resources/card_column_drag_strategy.tres @@ -0,0 +1,11 @@ +[gd_resource type="Resource" script_class="CardColumnDragStrategy" load_steps=2 format=3 uid="uid://cb1c1q85i4ka2"] + +[ext_resource type="Script" uid="uid://c4eh7en1au78a" path="res://example_solitaire/scripts/card_column.gd" id="1_auo7v"] + +[resource] +script = ExtResource("1_auo7v") +can_select = true +can_remove = true +can_reorder = true +can_insert = true +metadata/_custom_type_script = "uid://c4eh7en1au78a" diff --git a/example_solitaire/resources/suit_discard_drag_strategy.tres b/example_solitaire/resources/suit_discard_drag_strategy.tres new file mode 100644 index 0000000..7aa696e --- /dev/null +++ b/example_solitaire/resources/suit_discard_drag_strategy.tres @@ -0,0 +1,11 @@ +[gd_resource type="Resource" script_class="SuitDiscard" load_steps=2 format=3 uid="uid://dl7ll3l0opi0a"] + +[ext_resource type="Script" uid="uid://crx78y6320odd" path="res://example_solitaire/scripts/suit_discard.gd" id="1_potsm"] + +[resource] +script = ExtResource("1_potsm") +can_select = false +can_remove = false +can_reorder = false +can_insert = true +metadata/_custom_type_script = "uid://crx78y6320odd" diff --git a/example_solitaire/scenes/solitaire.tscn b/example_solitaire/scenes/solitaire.tscn index c3fe79c..6ff72d1 100644 --- a/example_solitaire/scenes/solitaire.tscn +++ b/example_solitaire/scenes/solitaire.tscn @@ -1,13 +1,13 @@ -[gd_scene load_steps=40 format=3 uid="uid://b3nx7g0iu2cd3"] +[gd_scene load_steps=29 format=3 uid="uid://b3nx7g0iu2cd3"] [ext_resource type="Script" uid="uid://btwpxkyhem6kk" path="res://example_solitaire/scenes/solitaire.gd" id="1_vfkpr"] [ext_resource type="Script" uid="uid://bgkontnk0cnl" path="res://addons/card_3d/scripts/drag_controller.gd" id="2_evxo0"] [ext_resource type="PackedScene" uid="uid://d1uvcisduvvj" path="res://addons/card_3d/scenes/card_collection_3d.tscn" id="3_kmjqy"] [ext_resource type="Script" uid="uid://dsyors6p1ph7" path="res://addons/card_3d/scripts/card_layouts/pile_card_layout.gd" id="4_ykggm"] -[ext_resource type="Script" uid="uid://c4eh7en1au78a" path="res://example_solitaire/scripts/card_column.gd" id="5_j26y4"] -[ext_resource type="Script" uid="uid://crx78y6320odd" path="res://example_solitaire/scripts/suit_discard.gd" id="5_vnftc"] [ext_resource type="Script" uid="uid://cpcw405f10750" path="res://example_solitaire/scripts/stack_layout.gd" id="5_y307u"] +[ext_resource type="Resource" uid="uid://dl7ll3l0opi0a" path="res://example_solitaire/resources/suit_discard_drag_strategy.tres" id="6_qw2g7"] [ext_resource type="Shape3D" uid="uid://b2q35fk3mga4d" path="res://example_solitaire/shapes/discard_collision.tres" id="7_w66lm"] +[ext_resource type="Resource" uid="uid://cb1c1q85i4ka2" path="res://example_solitaire/resources/card_column_drag_strategy.tres" id="9_qw2g7"] [ext_resource type="Shape3D" uid="uid://b4ul43sikpt87" path="res://example_solitaire/shapes/column_collision.tres" id="9_w66lm"] [ext_resource type="Script" uid="uid://drpbrbrd8kfxn" path="res://addons/card_3d/scripts/card_collection/drag_strategy.gd" id="9_xhcv4"] [ext_resource type="PackedScene" uid="uid://cviptf2wh1pc0" path="res://example_solitaire/scenes/pile_marker.tscn" id="9_xrvyx"] @@ -36,144 +36,56 @@ script = ExtResource("4_ykggm") pile_y_offset = 0.0 metadata/_custom_type_script = "uid://dsyors6p1ph7" -[sub_resource type="Resource" id="Resource_cl47x"] -script = ExtResource("5_vnftc") -can_select = false -can_remove = false -can_reorder = false -can_insert = true -metadata/_custom_type_script = "uid://crx78y6320odd" - [sub_resource type="Resource" id="Resource_i4hcm"] script = ExtResource("4_ykggm") pile_y_offset = 0.0 metadata/_custom_type_script = "uid://dsyors6p1ph7" -[sub_resource type="Resource" id="Resource_mrd3s"] -script = ExtResource("5_vnftc") -can_select = false -can_remove = false -can_reorder = false -can_insert = true -metadata/_custom_type_script = "uid://crx78y6320odd" - [sub_resource type="Resource" id="Resource_d026l"] script = ExtResource("4_ykggm") pile_y_offset = 0.0 metadata/_custom_type_script = "uid://dsyors6p1ph7" -[sub_resource type="Resource" id="Resource_tpxco"] -script = ExtResource("5_vnftc") -can_select = false -can_remove = false -can_reorder = false -can_insert = true -metadata/_custom_type_script = "uid://crx78y6320odd" - [sub_resource type="Resource" id="Resource_y6eo3"] script = ExtResource("4_ykggm") pile_y_offset = 0.0 metadata/_custom_type_script = "uid://dsyors6p1ph7" -[sub_resource type="Resource" id="Resource_d1so3"] -script = ExtResource("5_vnftc") -can_select = false -can_remove = false -can_reorder = false -can_insert = true -metadata/_custom_type_script = "uid://crx78y6320odd" - [sub_resource type="Resource" id="Resource_x8i2t"] script = ExtResource("5_y307u") distance = 0.8 metadata/_custom_type_script = "uid://cpcw405f10750" -[sub_resource type="Resource" id="Resource_jw1jw"] -script = ExtResource("5_j26y4") -can_select = true -can_remove = true -can_reorder = true -can_insert = true -metadata/_custom_type_script = "uid://c4eh7en1au78a" - [sub_resource type="Resource" id="Resource_q5e5c"] script = ExtResource("5_y307u") distance = 0.8 metadata/_custom_type_script = "uid://cpcw405f10750" -[sub_resource type="Resource" id="Resource_xhcv4"] -script = ExtResource("5_j26y4") -can_select = true -can_remove = true -can_reorder = true -can_insert = true -metadata/_custom_type_script = "uid://c4eh7en1au78a" - [sub_resource type="Resource" id="Resource_xy1l5"] script = ExtResource("5_y307u") distance = 0.8 metadata/_custom_type_script = "uid://cpcw405f10750" -[sub_resource type="Resource" id="Resource_w66lm"] -script = ExtResource("5_j26y4") -can_select = true -can_remove = true -can_reorder = true -can_insert = true -metadata/_custom_type_script = "uid://c4eh7en1au78a" - [sub_resource type="Resource" id="Resource_tu0lf"] script = ExtResource("5_y307u") distance = 0.8 metadata/_custom_type_script = "uid://cpcw405f10750" -[sub_resource type="Resource" id="Resource_qw2g7"] -script = ExtResource("5_j26y4") -can_select = true -can_remove = true -can_reorder = true -can_insert = true -metadata/_custom_type_script = "uid://c4eh7en1au78a" - [sub_resource type="Resource" id="Resource_eya50"] script = ExtResource("5_y307u") distance = 0.8 metadata/_custom_type_script = "uid://cpcw405f10750" -[sub_resource type="Resource" id="Resource_5orty"] -script = ExtResource("5_j26y4") -can_select = true -can_remove = true -can_reorder = true -can_insert = true -metadata/_custom_type_script = "uid://c4eh7en1au78a" - [sub_resource type="Resource" id="Resource_wxkx0"] script = ExtResource("5_y307u") distance = 0.8 metadata/_custom_type_script = "uid://cpcw405f10750" -[sub_resource type="Resource" id="Resource_awgux"] -script = ExtResource("5_j26y4") -can_select = true -can_remove = true -can_reorder = true -can_insert = true -metadata/_custom_type_script = "uid://c4eh7en1au78a" - [sub_resource type="Resource" id="Resource_mimnj"] script = ExtResource("5_y307u") distance = 0.8 metadata/_custom_type_script = "uid://cpcw405f10750" -[sub_resource type="Resource" id="Resource_23sxf"] -script = ExtResource("5_j26y4") -can_select = true -can_remove = true -can_reorder = true -can_insert = true -metadata/_custom_type_script = "uid://c4eh7en1au78a" - [sub_resource type="Resource" id="Resource_bpv8x"] script = ExtResource("4_ykggm") pile_y_offset = 0.0 @@ -214,7 +126,7 @@ drag_strategy = SubResource("Resource_n03b6") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 7, 0) highlight_on_hover = false card_layout_strategy = SubResource("Resource_ifhob") -drag_strategy = SubResource("Resource_cl47x") +drag_strategy = ExtResource("6_qw2g7") dropzone_collision_shape = ExtResource("7_w66lm") dropzone_z_offset = 0.0 @@ -222,7 +134,7 @@ dropzone_z_offset = 0.0 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 7, 0) highlight_on_hover = false card_layout_strategy = SubResource("Resource_i4hcm") -drag_strategy = SubResource("Resource_mrd3s") +drag_strategy = ExtResource("6_qw2g7") dropzone_collision_shape = ExtResource("7_w66lm") dropzone_z_offset = 0.0 @@ -230,7 +142,7 @@ dropzone_z_offset = 0.0 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5, 7, 0) highlight_on_hover = false card_layout_strategy = SubResource("Resource_d026l") -drag_strategy = SubResource("Resource_tpxco") +drag_strategy = ExtResource("6_qw2g7") dropzone_collision_shape = ExtResource("7_w66lm") dropzone_z_offset = 0.0 @@ -238,7 +150,7 @@ dropzone_z_offset = 0.0 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9, 7, 0) highlight_on_hover = false card_layout_strategy = SubResource("Resource_y6eo3") -drag_strategy = SubResource("Resource_d1so3") +drag_strategy = ExtResource("6_qw2g7") dropzone_collision_shape = ExtResource("7_w66lm") dropzone_z_offset = 0.0 @@ -246,7 +158,7 @@ dropzone_z_offset = 0.0 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15, 0, 0) highlight_on_hover = false card_layout_strategy = SubResource("Resource_x8i2t") -drag_strategy = SubResource("Resource_jw1jw") +drag_strategy = ExtResource("9_qw2g7") dropzone_collision_shape = ExtResource("9_w66lm") dropzone_z_offset = 0.0 @@ -254,7 +166,7 @@ dropzone_z_offset = 0.0 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11, 0, 0) highlight_on_hover = false card_layout_strategy = SubResource("Resource_q5e5c") -drag_strategy = SubResource("Resource_xhcv4") +drag_strategy = ExtResource("9_qw2g7") dropzone_collision_shape = ExtResource("9_w66lm") dropzone_z_offset = 0.0 @@ -262,7 +174,7 @@ dropzone_z_offset = 0.0 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7, 0, 0) highlight_on_hover = false card_layout_strategy = SubResource("Resource_xy1l5") -drag_strategy = SubResource("Resource_w66lm") +drag_strategy = ExtResource("9_qw2g7") dropzone_collision_shape = ExtResource("9_w66lm") dropzone_z_offset = 0.0 @@ -270,7 +182,7 @@ dropzone_z_offset = 0.0 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, 0) highlight_on_hover = false card_layout_strategy = SubResource("Resource_tu0lf") -drag_strategy = SubResource("Resource_qw2g7") +drag_strategy = ExtResource("9_qw2g7") dropzone_collision_shape = ExtResource("9_w66lm") dropzone_z_offset = 0.0 @@ -278,7 +190,7 @@ dropzone_z_offset = 0.0 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0) highlight_on_hover = false card_layout_strategy = SubResource("Resource_eya50") -drag_strategy = SubResource("Resource_5orty") +drag_strategy = ExtResource("9_qw2g7") dropzone_collision_shape = ExtResource("9_w66lm") dropzone_z_offset = 0.0 @@ -286,7 +198,7 @@ dropzone_z_offset = 0.0 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5, 0, 0) highlight_on_hover = false card_layout_strategy = SubResource("Resource_wxkx0") -drag_strategy = SubResource("Resource_awgux") +drag_strategy = ExtResource("9_qw2g7") dropzone_collision_shape = ExtResource("9_w66lm") dropzone_z_offset = 0.0 @@ -294,7 +206,7 @@ dropzone_z_offset = 0.0 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9, 0, 0) highlight_on_hover = false card_layout_strategy = SubResource("Resource_mimnj") -drag_strategy = SubResource("Resource_23sxf") +drag_strategy = ExtResource("9_qw2g7") dropzone_collision_shape = ExtResource("9_w66lm") dropzone_z_offset = 0.0 diff --git a/example_solitaire/scripts/card_column.gd b/example_solitaire/scripts/card_column.gd index 31ee474..bbe6f26 100644 --- a/example_solitaire/scripts/card_column.gd +++ b/example_solitaire/scripts/card_column.gd @@ -1,7 +1,11 @@ class_name CardColumnDragStrategy extends DragStrategy -func can_insert_card(card: FaceCard3D, to_collection, _from_collection) -> bool: +func can_insert_card( + card: FaceCard3D, + to_collection: CardCollection3D, + _from_collection: CardCollection3D + ) -> bool: var cards = to_collection.cards if cards.size() == 0: diff --git a/example_solitaire/scripts/suit_discard.gd b/example_solitaire/scripts/suit_discard.gd index 1b41cac..516310b 100644 --- a/example_solitaire/scripts/suit_discard.gd +++ b/example_solitaire/scripts/suit_discard.gd @@ -5,10 +5,11 @@ func can_insert_card(card: FaceCard3D, to_collection: CardCollection3D, from_col if from_collection.card_indicies.has(card) and from_collection.card_indicies[card] < from_collection.cards.size() - 1: return false - if to_collection.cards.size() == 0: + var to_cards = to_collection.cards + if to_cards.size() == 0: return card.rank == FaceCards.Rank.ACE - var last_card = to_collection.cards[to_collection.cards.size() - 1] + var last_card = to_cards[to_cards.size() - 1] var is_next_rank = (card.rank == last_card.rank + 1) or (last_card.rank == FaceCards.Rank.ACE and card.rank == FaceCards.Rank.TWO) var is_same_suit = last_card.suit == card.suit diff --git a/example_solitaire/shapes/discard_collision.tres b/example_solitaire/shapes/discard_collision.tres index 5478505..ede41dc 100644 --- a/example_solitaire/shapes/discard_collision.tres +++ b/example_solitaire/shapes/discard_collision.tres @@ -1,4 +1,5 @@ [gd_resource type="BoxShape3D" format=3 uid="uid://b2q35fk3mga4d"] [resource] +resource_name = "DiscardCollision" size = Vector3(4, 7, 0.5) From f1711b1046ce2310ee6697f9d187a13a2b37dbac Mon Sep 17 00:00:00 2001 From: Tyson Decker Date: Fri, 22 Aug 2025 09:35:53 -0600 Subject: [PATCH 5/5] clean up mixed tabs/spaces --- addons/card_3d/scripts/card_collection/drag_strategy.gd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/card_3d/scripts/card_collection/drag_strategy.gd b/addons/card_3d/scripts/card_collection/drag_strategy.gd index 902401d..806987f 100644 --- a/addons/card_3d/scripts/card_collection/drag_strategy.gd +++ b/addons/card_3d/scripts/card_collection/drag_strategy.gd @@ -7,10 +7,10 @@ DragStrategy This module defines an interface that describes how cards can drag from different collections. It can be configured either by: 1. Setting the drag strategy on your collection to a new DragStrategy resource via the Inspector - (Add Resource → DragStrategy) and configuring the default boolean values. + (Add Resource → DragStrategy) and configuring the default boolean values. 2. Creating a custom script that extends DragStrategy and overriding the hooks - (can_select_card, can_remove_card, can_reorder_card, can_insert_card) - to implement checks based on the card and collection. + (can_select_card, can_remove_card, can_reorder_card, can_insert_card) + to implement checks based on the card and collection. """