fixes merge conflicts

This commit is contained in:
Nathan Singer 2025-04-27 23:51:36 -04:00
commit 04ae9b856b
18 changed files with 177 additions and 111 deletions

View File

@ -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!"
)

View File

@ -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")

View File

@ -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))

View File

@ -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.

15
hand.gd Normal file
View File

@ -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

1
hand.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://dvu4gdhqjejeo

View File

@ -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)

View File

@ -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)

View File

@ -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")

View File

@ -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)
]

View File

@ -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

24
scenes/card/card.tscn Normal file
View File

@ -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"]

0
scenes/card/input.gd Normal file
View File

1
scenes/card/input.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://dhgk6fhw8oua0

22
scenes/card/tween.gd Normal file
View File

@ -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)

1
scenes/card/tween.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://bkk0pyypi1id7

View File

@ -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.