diff --git a/caching.gd b/caching.gd index 32906b4..72bea0d 100644 --- a/caching.gd +++ b/caching.gd @@ -9,37 +9,40 @@ var _emitted_done = 0 signal fetch_start var _emitted_start = 0 - var _consts = preload("res://data/consts.gd") + func _all_downloads_done() -> bool: return _emitted_done == _emitted_start + func _setup_cache_in_mem(): var file = FileAccess.open("user://bulk.json", FileAccess.READ) _bulk_data = JSON.parse_string(file.get_as_text()) file.close() - + func setup() -> Error: if !FileAccess.file_exists("user://bulk.json"): get_bulk_data(false) push_error("Bulk Data was not downloaded! Downloading now!") return FAILED - + if !_all_downloads_done(): push_error("Not done downloading Bulk Data.") return FAILED - + _setup_cache_in_mem() return OK + func _init() -> void: - _req_headers = PackedStringArray(["User-Agent: " + _consts.APP_NAME + "/" + _consts.APP_VERSION, "Accept: */*"]) - + _req_headers = PackedStringArray( + ["User-Agent: " + _consts.APP_NAME + "/" + _consts.APP_VERSION, "Accept: */*"] + ) + fetch_done.connect(_on_end_emit) fetch_start.connect(_on_start_emit) - func _on_start_emit() -> void: @@ -49,20 +52,22 @@ func _on_start_emit() -> void: func _on_end_emit() -> void: _emitted_done += 1 + func has_emitted_all() -> bool: return _emitted_start == _emitted_done func _cache_error(err: String) -> String: return "CACHE::ERROR::" + err + "\n" - + func _get_dict_from_file(filepath: String) -> Dictionary: var file = FileAccess.open(filepath, FileAccess.READ) var data = JSON.parse_string(file.get_as_text()) - + return data + ## get_card_data_from_name ## ## _name: String [br] @@ -123,90 +128,92 @@ func _get_card_data_from_bulk(dict_entry: Dictionary) -> Dictionary: return dict_entry + func _fetch_card_img(data: Dictionary) -> Error: fetch_start.emit() if FileAccess.file_exists("user://card_cache/" + data["id"] + "card.png"): return OK - + var httpr = HTTPRequest.new() add_child(httpr) - + var err = httpr.request((data["image_uris"])["png"], _req_headers) if err != OK: push_error(_cache_error("GET_REQUEST") + "An error occured in the Scryfall request.") return FAILED var resp = await httpr.request_completed - + var img = Image.new() err = img.load_png_from_buffer(resp[3]) if err != OK: push_error(_cache_error("IMG_LOADING") + "Couldn't load the image.") return FAILED - + var dir = DirAccess.open("user://") dir.make_dir_recursive("user://card_cache/" + data["id"] + "/") dir = null - + img.save_png("user://card_cache/" + data["id"] + "/card.png") img = null - + fetch_done.emit() - + return OK + func get_bulk_data(force: bool) -> Error: if FileAccess.file_exists("user://bulk.json"): if force: DirAccess.remove_absolute("user://bulk.json") else: return OK - print("downloading ") - var httpr = HTTPRequest.new() add_child(httpr) - + var error = httpr.request("https://api.scryfall.com/bulk-data/unique-artwork", _req_headers) if error != OK: push_error(_cache_error("GET_REQUEST") + "An error occurred in the Scryfall request.") return FAILED - + var response = await httpr.request_completed if response[0] != HTTPRequest.RESULT_SUCCESS: push_error(_cache_error("GET_REQUEST") + "Failed to fetch card data from Scryfall") return FAILED - + var unprocessed_body = response[3].get_string_from_utf8() var card_content = JSON.parse_string(unprocessed_body) if card_content == null: push_error(_cache_error("PARSING") + "Failed to parse the Scryfall card results.") return FAILED - - + error = httpr.request(card_content["download_uri"], _req_headers) if error != OK: push_error(_cache_error("GET_REQUEST") + "An error occurred in the Scryfall request.") return FAILED - + response = await httpr.request_completed if response[0] != HTTPRequest.RESULT_SUCCESS: push_error(_cache_error("GET_REQUEST") + "Failed to fetch card data from Scryfall") return FAILED - + unprocessed_body = response[3].get_string_from_utf8() card_content = JSON.parse_string(unprocessed_body) if card_content == null: push_error(_cache_error("PARSING") + "Failed to parse the Scryfall card results.") return FAILED - + var data_cache = FileAccess.open("user://bulk.json", FileAccess.WRITE) data_cache.store_string(unprocessed_body) data_cache.close() - + fetch_done.emit() - + return OK + func _notification(what): if what == NOTIFICATION_PREDELETE: if !_all_downloads_done(): - push_error("ERR::MEM::CACHE\nCache being deleted before all threads have finished processing!") + push_error( + "ERR::MEM::CACHE\nCache being deleted before all threads have finished processing!" + ) diff --git a/card.tscn b/card.tscn deleted file mode 100644 index 204a420..0000000 --- a/card.tscn +++ /dev/null @@ -1,11 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://cah3mvdnom1xg"] - -[ext_resource type="Script" uid="uid://b3yqd1qu7dyq" path="res://card.gd" id="1_kikvd"] - -[node name="Card" type="TextureRect"] -offset_left = 794.0 -offset_top = 79.0 -offset_right = 919.0 -offset_bottom = 254.0 -mouse_default_cursor_shape = 2 -script = ExtResource("1_kikvd") diff --git a/deck_input.gd b/deck_input.gd index 040a5be..2805d4c 100644 --- a/deck_input.gd +++ b/deck_input.gd @@ -4,6 +4,7 @@ var _caching = preload("res://caching.gd") var _decklist + func _init() -> void: _decklist = Dictionary() @@ -31,7 +32,7 @@ func _convert_mtgo_to_cache_lookup(decklist: String) -> Dictionary: var words = line.split(" ", false, 1) if words.size() != 2: continue - + _cards[words[1]] = words[0] return _cards @@ -62,7 +63,6 @@ func _do_decklist_cache(_queries: Dictionary) -> void: push_error("Failed to find card: " + query) continue _decklist[entry["id"]] = _queries[query] - cache.fetch_done.connect(_do_free.bind(cache)) diff --git a/field.gd b/field.gd index 5ad1a16..546071d 100644 --- a/field.gd +++ b/field.gd @@ -3,7 +3,7 @@ extends TextureRect var _screen_size: Vector2 var _colors: Array[Color] -var _card_scene = preload("res://card.tscn") +var _card_class = preload("res://scenes/card/card.tscn") # Called when the node enters the scene tree for the first time. @@ -11,7 +11,7 @@ func _ready() -> void: # TODO: Calculate this field's scale and position based on which no# field this is. _screen_size = get_viewport_rect().size - var card = _card_scene.instantiate() + var card = _card_class.instantiate() # TODO: Currently working with an already-cached card with a known ID to load this. # Later on, the cards should be pulling the IDs directly from the library's list of IDs. diff --git a/hand.gd b/hand.gd new file mode 100644 index 0000000..62621b8 --- /dev/null +++ b/hand.gd @@ -0,0 +1,15 @@ +extends StaticBody2D + +var cards: Array[Node] = [] + +var _card_class = preload("res://scenes/card/card.tscn") + + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + pass diff --git a/hand.gd.uid b/hand.gd.uid new file mode 100644 index 0000000..92d251d --- /dev/null +++ b/hand.gd.uid @@ -0,0 +1 @@ +uid://dvu4gdhqjejeo diff --git a/library.gd b/library.gd index cd5c50a..53506dc 100644 --- a/library.gd +++ b/library.gd @@ -19,6 +19,7 @@ func _init(_decklist: Dictionary) -> void: for i in _num: lib_cards.push_back(card) + func add_cards(cards: Array, top: bool) -> void: for card in cards: add_card(card, top) diff --git a/player.gd b/player.gd index d2006b9..c2ca477 100644 --- a/player.gd +++ b/player.gd @@ -1,18 +1,17 @@ extends Node2D -var _card_class = preload("res://card.tscn") +var _card_class = preload("res://scenes/card/card.tscn") var field_scene = preload("res://field.tscn") var fields: Array[Node] = [] var decks: Array[Dictionary] - # Called when the node enters the scene tree for the first time. func _ready() -> void: # The first field in the array will be the player's own field. # Might be a better idea to have that in a seperate variable? idk - + var card = _card_class.instantiate() # TODO: Currently working with an already-cached card with a known ID to load this. @@ -20,7 +19,7 @@ func _ready() -> void: card.init("d3f10f07-7cfe-4a6f-8de6-373e367a731b") add_child(card) - + #fields.append(field_scene.instantiate()) #var colors: Array[Color] = [Color(1, 0, 1)] #fields[0].set_colors(colors) diff --git a/player.tscn b/player.tscn index f50248a..5860663 100644 --- a/player.tscn +++ b/player.tscn @@ -1,12 +1,21 @@ -[gd_scene load_steps=3 format=3 uid="uid://cx0vga81xwckh"] +[gd_scene load_steps=5 format=3 uid="uid://cx0vga81xwckh"] [ext_resource type="Script" uid="uid://w2rqm1u7p7im" path="res://player.gd" id="1_4flbx"] +[ext_resource type="Script" uid="uid://dvu4gdhqjejeo" path="res://hand.gd" id="2_i3pqv"] [ext_resource type="Script" uid="uid://bc51go8t8uvts" path="res://library.gd" id="2_onrkg"] +[sub_resource type="RectangleShape2D" id="RectangleShape2D_onrkg"] +size = Vector2(1920, 200) + [node name="Player" type="Node2D"] script = ExtResource("1_4flbx") -[node name="Hand" type="Node2D" parent="."] +[node name="Hand" type="StaticBody2D" parent="."] +script = ExtResource("2_i3pqv") + +[node name="CollisionArea" type="CollisionShape2D" parent="Hand"] +position = Vector2(960, 980) +shape = SubResource("RectangleShape2D_onrkg") [node name="Library" type="Node2D" parent="."] script = ExtResource("2_onrkg") diff --git a/project.godot b/project.godot index d83b7a6..7d1eaaf 100644 --- a/project.godot +++ b/project.godot @@ -27,7 +27,7 @@ enabled=PackedStringArray() [input] -default_action={ +MAIN={ "deadzone": 0.2, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) ] diff --git a/card.gd b/scenes/card/card.gd similarity index 65% rename from card.gd rename to scenes/card/card.gd index 54922ea..f80c694 100644 --- a/card.gd +++ b/scenes/card/card.gd @@ -1,80 +1,75 @@ -extends TextureRect -#extends Sprite2D +extends Node2D ## The card class ## ## Represents an instance of a card to be displayed on the tabletop. ## Contains helper text for the text, the cards ID, and the image path. -enum pivot { - ROTATE_0, - ROTATE_90, - ROTATE_180, - ROTATE_270 -} - -var current_pivot = pivot.ROTATE_0 - +# Card information. var card_id: String var card_name: String var card_type: String var oracle_text: String -var is_dragging = false -var is_pivot = false +# Card properties. +var tapped: bool + +# Card input state. +var is_focused: bool # Is the card a focus? +var is_dragging: bool # Is the card currently being dragged? -var delay = 5.0 var mouse_offset: Vector2 - -func _pivot() -> int: - var deg: int - match current_pivot: - pivot.ROTATE_0: - deg = 0 - pivot.ROTATE_90: - deg = 90 - pivot.ROTATE_180: - deg = 180 - pivot.ROTATE_270: - deg = 270 - return deg - - func _physics_process(delta: float) -> void: - if is_dragging == true: - var tween = get_tree().create_tween() - tween.tween_property(self, "position", get_global_mouse_position() - mouse_offset, delay * delta) - if is_pivot == true: - var tween = get_tree().create_tween() - tween.tween_property(self, "rotation_degrees", _pivot(), delta * delay) - is_pivot = false - + if is_focused: + # TODO: Export handling keypresses to its own area. + if Input.is_action_just_pressed("MAIN"): + tapped = not tapped + $TweenController.tap(tapped, delta) -func _gui_input(event: InputEvent) -> void: + if is_dragging: + $TweenController.move_to(get_global_mouse_position() - mouse_offset, delta) + + +func _on_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void: if event is not InputEventMouseButton: return + match event.button_index: + # MOUSE BUTTONS MOUSE_BUTTON_LEFT: if event.pressed: - is_dragging = true + Input.set_default_cursor_shape(Input.CURSOR_DRAG) mouse_offset = get_global_mouse_position() - global_position + is_dragging = true else: + Input.set_default_cursor_shape(Input.CURSOR_POINTING_HAND) is_dragging = false MOUSE_BUTTON_RIGHT: + # TODO: Tooltip menu for right-button clicking on cards. pass - -func _unhandled_key_input(event: InputEvent) -> void: - if not event.is_action_pressed("default_action"): + +func _on_mouse_entered() -> void: + # Do not care about mouse entering if we're dragging the card. + if is_dragging: return - if current_pivot == pivot.ROTATE_0: - current_pivot = pivot.ROTATE_90 - is_pivot = true - else: - current_pivot = pivot.ROTATE_0 - is_pivot = true - set_pivot_offset(size / 2) + + Input.set_default_cursor_shape(Input.CURSOR_POINTING_HAND) + $TweenController.scale(1.05) + is_focused = true + + +func _on_mouse_exited() -> void: + # Do not care about mouse exiting if we're dragging the card. + if is_dragging: + return + + Input.set_default_cursor_shape(Input.CURSOR_ARROW) + $TweenController.scale(1.0) + + is_focused = false + func _card_error(error_type: String) -> String: return "ERROR::CARD::%s::%s::%s::\n" % [card_id, card_name, error_type] @@ -82,7 +77,7 @@ func _card_error(error_type: String) -> String: func init(id: String) -> void: card_id = id - + func _ready() -> void: var load_status = _load_card() @@ -91,8 +86,6 @@ func _ready() -> void: # if the card is not cached, perhaps a placeholder blank card can be used instead? # Setting that up can be put here later... push_error("Failed to load card.") - - set_pivot_offset(size / 2) func _load_card() -> Error: @@ -140,16 +133,12 @@ func _load_image() -> Error: push_error("%sCard on-board image failed to load correctly" % _card_error("IMAGE")) return FAILED - - # TODO: Get the size from the node or some constant variable. + var size = $Area2D/CollisionShape2D.shape.size image.resize(int(size.x), int(size.y), Image.INTERPOLATE_LANCZOS) - - var image_texture = ImageTexture.new() image_texture.set_image(image) - #expand_mode = TextureRect.EXPAND_FIT_WIDTH - texture = image_texture + $Sprite2D.texture = image_texture return OK diff --git a/card.gd.uid b/scenes/card/card.gd.uid similarity index 100% rename from card.gd.uid rename to scenes/card/card.gd.uid diff --git a/scenes/card/card.tscn b/scenes/card/card.tscn new file mode 100644 index 0000000..1d69f81 --- /dev/null +++ b/scenes/card/card.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=4 format=3 uid="uid://cah3mvdnom1xg"] + +[ext_resource type="Script" uid="uid://b3yqd1qu7dyq" path="res://scenes/card/card.gd" id="1_kikvd"] +[ext_resource type="Script" uid="uid://bkk0pyypi1id7" path="res://scenes/card/tween.gd" id="2_imta7"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_kikvd"] +size = Vector2(125, 175) + +[node name="Card" type="Node2D"] +script = ExtResource("1_kikvd") + +[node name="Sprite2D" type="Sprite2D" parent="."] + +[node name="Area2D" type="Area2D" parent="."] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +shape = SubResource("RectangleShape2D_kikvd") + +[node name="TweenController" type="Node2D" parent="."] +script = ExtResource("2_imta7") + +[connection signal="input_event" from="Area2D" to="." method="_on_input_event"] +[connection signal="mouse_entered" from="Area2D" to="." method="_on_mouse_entered"] +[connection signal="mouse_exited" from="Area2D" to="." method="_on_mouse_exited"] diff --git a/scenes/card/input.gd b/scenes/card/input.gd new file mode 100644 index 0000000..e69de29 diff --git a/scenes/card/input.gd.uid b/scenes/card/input.gd.uid new file mode 100644 index 0000000..0b4fbf9 --- /dev/null +++ b/scenes/card/input.gd.uid @@ -0,0 +1 @@ +uid://dhgk6fhw8oua0 diff --git a/scenes/card/tween.gd b/scenes/card/tween.gd new file mode 100644 index 0000000..f52ea6e --- /dev/null +++ b/scenes/card/tween.gd @@ -0,0 +1,22 @@ +extends Node + +@export var move_speed = 1.0 +@export var tap_speed = 5.0 +@export var scale_speed = 0.1 + + +func move_to(location: Vector2, delta: float) -> void: + var tween = create_tween() + tween.tween_property(get_parent(), "position", location, delta * move_speed) + + +func tap(tapped: bool, delta: float) -> void: + var tween = create_tween() + var rotation = 90 if tapped else 0 + tween.tween_property(get_parent(), "rotation_degrees", rotation, delta * tap_speed) + + +func scale(scalar: float) -> void: + var tween = create_tween() + var new_scale = Vector2.ONE * scalar + tween.tween_property(get_parent(), "scale", new_scale, scale_speed) diff --git a/scenes/card/tween.gd.uid b/scenes/card/tween.gd.uid new file mode 100644 index 0000000..3719bc7 --- /dev/null +++ b/scenes/card/tween.gd.uid @@ -0,0 +1 @@ +uid://bkk0pyypi1id7 diff --git a/tabletop.gd b/tabletop.gd index 70531b1..c7f9cd3 100644 --- a/tabletop.gd +++ b/tabletop.gd @@ -90,14 +90,16 @@ var cards = "1 Arcane Signet 1 ClavileƱo, First of the Blessed" + func _bulk_callback(cache) -> void: cache.setup() + # Called when the node enters the scene tree for the first time. func _ready() -> void: var cache = _caching.new() add_child(cache) - + if cache.setup() != OK: cache.fetch_done.connect(_bulk_callback.bind(cache)) # TODO: Create 2-4 player instances as children of this tabletop node. @@ -105,13 +107,19 @@ func _ready() -> void: var player = player_class.new() add_child(player) move_child(player, 0) - + cache.get_card_data_from_name("1996 World Champion") +<<<<<<< HEAD var deck = deck_input.new() add_child(deck) deck.add_new_deck(cards, "Blood rites") +======= + + # var deck = deck_input.new(cards) + # add_child(deck) +>>>>>>> card-rework pass # Replace with function body.