Compare commits
19 Commits
04ae9b856b
...
main
Author | SHA1 | Date | |
---|---|---|---|
1a5372f713 | |||
c125d1b70a | |||
bd5b734d79 | |||
31175b4ecd | |||
76a23aab5c | |||
6eb80f768b | |||
1fe7500dd2 | |||
1c5c4728a3 | |||
75767e927d | |||
c684a00f3a | |||
a496bb3982 | |||
a83261cf09 | |||
32bf3be0cd | |||
999c7989f3 | |||
a7aad7d99f | |||
2f5185d22c | |||
933e6b715c | |||
45919dc5ae | |||
709859abad |
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,6 @@
|
||||
# Godot 4+ specific ignores
|
||||
.godot/
|
||||
/android/
|
||||
|
||||
# custom ignores
|
||||
symbol_cache/
|
||||
|
81
caching.gd
81
caching.gd
@ -32,6 +32,8 @@ func setup() -> Error:
|
||||
push_error("Not done downloading Bulk Data.")
|
||||
return FAILED
|
||||
|
||||
_fetch_mana_symbols()
|
||||
|
||||
_setup_cache_in_mem()
|
||||
return OK
|
||||
|
||||
@ -86,8 +88,8 @@ func get_card_data_from_id(id: String) -> Dictionary:
|
||||
|
||||
return _get_card_data_from_bulk(_search_results_generic("id", id))
|
||||
|
||||
|
||||
func _search_results_name(search_query: String) -> Dictionary:
|
||||
var selected_entry = null
|
||||
for entry in _bulk_data:
|
||||
if entry["layout"] == "art_series":
|
||||
continue
|
||||
@ -101,7 +103,6 @@ func _search_results_name(search_query: String) -> Dictionary:
|
||||
|
||||
|
||||
func _search_results_generic(field: String, search_query: String) -> Dictionary:
|
||||
var selected_entry = null
|
||||
for entry in _bulk_data:
|
||||
if entry["layout"] == "art_series":
|
||||
continue
|
||||
@ -120,7 +121,9 @@ func _get_card_data_from_bulk(dict_entry: Dictionary) -> Dictionary:
|
||||
dir.make_dir_recursive("user://card_cache/" + dict_entry["id"] + "/")
|
||||
dir = null
|
||||
|
||||
var file = FileAccess.open("user://card_cache/" + dict_entry["id"] + "/card.json", FileAccess.WRITE)
|
||||
var file = FileAccess.open(
|
||||
"user://card_cache/" + dict_entry["id"] + "/card.json", FileAccess.WRITE
|
||||
)
|
||||
file.store_line(JSON.stringify(dict_entry, "\t"))
|
||||
file.close()
|
||||
|
||||
@ -129,6 +132,78 @@ func _get_card_data_from_bulk(dict_entry: Dictionary) -> Dictionary:
|
||||
return dict_entry
|
||||
|
||||
|
||||
func _get_mana_img(symbol: String, img_url: String) -> Error:
|
||||
fetch_start.emit()
|
||||
if FileAccess.file_exists("res://symbol_cache/" + symbol + ".svg"):
|
||||
return OK
|
||||
|
||||
var httpr = HTTPRequest.new()
|
||||
add_child(httpr)
|
||||
|
||||
var err = httpr.request(img_url, _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_svg_from_buffer(resp[3])
|
||||
if err != OK:
|
||||
push_error(_cache_error("IMG_LOADING") + "Couldn't load the image.")
|
||||
return FAILED
|
||||
|
||||
if img.get_size() == Vector2i(100, 100):
|
||||
print("resizing")
|
||||
img.resize(20, 20, Image.INTERPOLATE_LANCZOS)
|
||||
|
||||
img.save_png(
|
||||
"res://symbol_cache/" + symbol.replace("/", "-").replace("{", "").replace("}", "") + ".png"
|
||||
)
|
||||
|
||||
img = null
|
||||
|
||||
fetch_done.emit()
|
||||
|
||||
return OK
|
||||
|
||||
|
||||
func _fetch_mana_symbols() -> Error:
|
||||
var mana_symbols: Dictionary = Dictionary()
|
||||
if DirAccess.dir_exists_absolute("res://symbol_cache"):
|
||||
return OK
|
||||
else:
|
||||
DirAccess.make_dir_absolute("res://symbol_cache")
|
||||
|
||||
var httpr = HTTPRequest.new()
|
||||
add_child(httpr)
|
||||
|
||||
var err = httpr.request("https://api.scryfall.com/symbology", _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 unprocessed_body = resp[3].get_string_from_utf8()
|
||||
var json_body = JSON.parse_string(unprocessed_body)
|
||||
for icon in json_body["data"]:
|
||||
err = await _get_mana_img(icon["symbol"], icon["svg_uri"])
|
||||
if err != OK:
|
||||
push_error("Couldn't fetch mana symbol " + icon["symbol"])
|
||||
mana_symbols[icon["symbol"]] = (
|
||||
"res://symbol_cache/"
|
||||
+ icon["symbol"].replace("/", "-").replace("{", "").replace("}", "")
|
||||
+ ".png"
|
||||
)
|
||||
print(icon["symbol"] + " image cached.")
|
||||
|
||||
var file = FileAccess.open("res://symbol_cache/symbols.json", FileAccess.WRITE)
|
||||
file.store_line(JSON.stringify(mana_symbols))
|
||||
file.close()
|
||||
|
||||
print("Done caching mana symbols.")
|
||||
return OK
|
||||
|
||||
|
||||
func _fetch_card_img(data: Dictionary) -> Error:
|
||||
fetch_start.emit()
|
||||
if FileAccess.file_exists("user://card_cache/" + data["id"] + "card.png"):
|
||||
|
@ -17,6 +17,7 @@ func _write_to_decks(_decks: Array) -> void:
|
||||
file.store_line(JSON.stringify(_decks))
|
||||
file.close()
|
||||
|
||||
|
||||
func load_decks() -> Array:
|
||||
if !FileAccess.file_exists("user://decks.json"):
|
||||
return []
|
||||
@ -25,6 +26,7 @@ func load_decks() -> Array:
|
||||
file.close()
|
||||
return JSON.parse_string(file_text)
|
||||
|
||||
|
||||
func _convert_mtgo_to_cache_lookup(decklist: String) -> Dictionary:
|
||||
var _cards = {}
|
||||
var lines = decklist.split("\n")
|
||||
@ -43,12 +45,12 @@ func _do_free(cache) -> void:
|
||||
cache.queue_free()
|
||||
|
||||
|
||||
func add_new_deck(cards: String, name: String, about = "") -> void:
|
||||
func add_new_deck(cards: String, _name: String, about = "") -> void:
|
||||
var _queries = _convert_mtgo_to_cache_lookup(cards)
|
||||
_do_decklist_cache(_queries)
|
||||
|
||||
var _decks = load_decks()
|
||||
_decks.push_back({"name": name, "about": about, "decklist": _queries})
|
||||
_decks.push_back({"name": _name, "about": about, "decklist": _queries})
|
||||
_write_to_decks(_decks)
|
||||
|
||||
|
||||
|
6
event_bus.gd
Normal file
6
event_bus.gd
Normal file
@ -0,0 +1,6 @@
|
||||
extends Node
|
||||
|
||||
@warning_ignore("unused_signal")
|
||||
signal card_on_hover(card_info, card_image)
|
||||
@warning_ignore("unused_signal")
|
||||
signal card_on_unhover
|
1
event_bus.gd.uid
Normal file
1
event_bus.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://b5re77jjgr8ca
|
@ -1,6 +1,6 @@
|
||||
extends Node2D
|
||||
|
||||
var _card_class = preload("res://card.gd")
|
||||
var _card_class = preload("res://scenes/card/card.gd")
|
||||
|
||||
# Library cards are represented as an array of card IDs.
|
||||
var lib_cards: Array[String]
|
||||
|
@ -7,18 +7,23 @@ 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()
|
||||
card.init("d3f10f07-7cfe-4a6f-8de6-373e367a731b")
|
||||
add_child(card)
|
||||
card.position = Vector2(100, 100)
|
||||
|
||||
# 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.
|
||||
card.init("d3f10f07-7cfe-4a6f-8de6-373e367a731b")
|
||||
|
||||
add_child(card)
|
||||
|
||||
|
||||
|
||||
|
||||
#fields.append(field_scene.instantiate())
|
||||
#var colors: Array[Color] = [Color(1, 0, 1)]
|
||||
|
@ -15,6 +15,10 @@ run/main_scene="uid://b4ldtb3gw0jlu"
|
||||
config/features=PackedStringArray("4.4", "Forward Plus")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[autoload]
|
||||
|
||||
EventBus="*res://event_bus.gd"
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_width=1920
|
||||
@ -32,3 +36,8 @@ MAIN={
|
||||
"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)
|
||||
]
|
||||
}
|
||||
SELECT={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
@ -5,140 +5,68 @@ extends Node2D
|
||||
## Contains helper text for the text, the cards ID, and the image path.
|
||||
|
||||
# Card information.
|
||||
var card_id: String
|
||||
var card_name: String
|
||||
var card_type: String
|
||||
var oracle_text: String
|
||||
var card_info: Dictionary
|
||||
var cached_image: Image
|
||||
|
||||
# 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 hovered: bool # Is the mouse currently on this card?
|
||||
var dragging: bool # Is the card currently being dragged?
|
||||
var focused: bool # Is this card currently a focus?
|
||||
|
||||
var mouse_offset: Vector2
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
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)
|
||||
|
||||
if is_dragging:
|
||||
$TweenController.move_to(get_global_mouse_position() - mouse_offset, delta)
|
||||
func init(id: String) -> void:
|
||||
card_info["id"] = id
|
||||
|
||||
|
||||
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:
|
||||
Input.set_default_cursor_shape(Input.CURSOR_DRAG)
|
||||
mouse_offset = get_global_mouse_position() - global_position
|
||||
is_dragging = true
|
||||
# This is called when we want to apply the behaviour of the mouse being
|
||||
# inside/outside the card when we can't trigger the enter/exit triggers.
|
||||
func check_hover() -> void:
|
||||
if hovered:
|
||||
_on_mouse_entered()
|
||||
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
|
||||
_on_mouse_exited()
|
||||
|
||||
|
||||
func error(error_type: String) -> String:
|
||||
return "ERROR::CARD::%s::%s::%s::\n" % [card_info["id"], card_info["name"], error_type]
|
||||
|
||||
|
||||
func colission_size() -> Vector2:
|
||||
return $Area2D/CollisionShape2D.shape.size
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
focused = hovered or dragging
|
||||
|
||||
$InputHandler.handle_inputs(delta)
|
||||
$TweenController.handle_constant_tweens(delta)
|
||||
|
||||
|
||||
func _on_mouse_entered() -> void:
|
||||
# Do not care about mouse entering if we're dragging the card.
|
||||
if is_dragging:
|
||||
hovered = true
|
||||
|
||||
# Do not apply any more effects if we're dragging the card.
|
||||
if dragging:
|
||||
return
|
||||
|
||||
Input.set_default_cursor_shape(Input.CURSOR_POINTING_HAND)
|
||||
$TweenController.scale(1.05)
|
||||
is_focused = true
|
||||
EventBus.emit_signal("card_on_hover", card_info, cached_image)
|
||||
|
||||
|
||||
func _on_mouse_exited() -> void:
|
||||
# Do not care about mouse exiting if we're dragging the card.
|
||||
if is_dragging:
|
||||
hovered = false
|
||||
|
||||
# Do not apply any more effects if we're dragging the card.
|
||||
if 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]
|
||||
|
||||
|
||||
func init(id: String) -> void:
|
||||
card_id = id
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
var load_status = _load_card()
|
||||
if load_status != OK:
|
||||
# TODO: No need to push another error as the failure state of loading does that already,
|
||||
# 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.")
|
||||
|
||||
|
||||
func _load_card() -> Error:
|
||||
if _load_data() != OK:
|
||||
return FAILED
|
||||
|
||||
if _load_image() != OK:
|
||||
return FAILED
|
||||
|
||||
return OK
|
||||
|
||||
|
||||
func _load_data() -> Error:
|
||||
var cached_json = FileAccess.get_file_as_string("user://card_cache/" + card_id + "/card.json")
|
||||
|
||||
if cached_json.is_empty():
|
||||
push_error("%s\nCard json data was not found in cache" % _card_error("CACHE"))
|
||||
return FAILED
|
||||
|
||||
var card_json = JSON.parse_string(cached_json)
|
||||
|
||||
if card_json == null:
|
||||
push_error("%s\nCard json data is could not be parsed as valid json" % _card_error("DATA"))
|
||||
return FAILED
|
||||
|
||||
card_name = card_json["name"]
|
||||
card_type = card_json["type_line"]
|
||||
oracle_text = card_json["oracle_text"]
|
||||
|
||||
return OK
|
||||
|
||||
|
||||
func _load_image() -> Error:
|
||||
# NOTE: Assuming we're going with using the .png cards on board.
|
||||
var cached_img = FileAccess.get_file_as_bytes("user://card_cache/" + card_id + "/card.png")
|
||||
|
||||
if cached_img.is_empty():
|
||||
push_error("%sCard on-board image was not found in cache" % _card_error("CACHE"))
|
||||
return FAILED
|
||||
|
||||
var image = Image.new()
|
||||
var image_status: Error = image.load_png_from_buffer(cached_img)
|
||||
|
||||
if image_status != OK:
|
||||
push_error("%sCard on-board image failed to load correctly" % _card_error("IMAGE"))
|
||||
return FAILED
|
||||
|
||||
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)
|
||||
|
||||
$Sprite2D.texture = image_texture
|
||||
|
||||
return OK
|
||||
EventBus.emit_signal("card_on_unhover")
|
||||
|
@ -1,7 +1,9 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://cah3mvdnom1xg"]
|
||||
[gd_scene load_steps=6 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"]
|
||||
[ext_resource type="Script" uid="uid://dhgk6fhw8oua0" path="res://scenes/card/input.gd" id="3_vtcvk"]
|
||||
[ext_resource type="Script" uid="uid://vckbno504iay" path="res://scenes/card/load.gd" id="4_g65cd"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kikvd"]
|
||||
size = Vector2(125, 175)
|
||||
@ -16,9 +18,14 @@ script = ExtResource("1_kikvd")
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
shape = SubResource("RectangleShape2D_kikvd")
|
||||
|
||||
[node name="TweenController" type="Node2D" parent="."]
|
||||
[node name="TweenController" type="Node" parent="."]
|
||||
script = ExtResource("2_imta7")
|
||||
|
||||
[connection signal="input_event" from="Area2D" to="." method="_on_input_event"]
|
||||
[node name="InputHandler" type="Node" parent="."]
|
||||
script = ExtResource("3_vtcvk")
|
||||
|
||||
[node name="DataLoader" type="Node" parent="."]
|
||||
script = ExtResource("4_g65cd")
|
||||
|
||||
[connection signal="mouse_entered" from="Area2D" to="." method="_on_mouse_entered"]
|
||||
[connection signal="mouse_exited" from="Area2D" to="." method="_on_mouse_exited"]
|
||||
|
@ -0,0 +1,27 @@
|
||||
extends Node
|
||||
|
||||
var card: Node
|
||||
var tween_controller: Node
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
card = get_parent()
|
||||
tween_controller = card.get_node("TweenController")
|
||||
|
||||
|
||||
func handle_inputs(delta: float) -> void:
|
||||
if not card.focused:
|
||||
# TODO: Global card actions, e.g. untapping everything.
|
||||
return
|
||||
|
||||
if Input.is_action_just_pressed("MAIN"):
|
||||
card.tapped = not card.tapped
|
||||
tween_controller.tap(card.tapped, delta)
|
||||
|
||||
if Input.is_action_just_pressed("SELECT"):
|
||||
card.dragging = true
|
||||
Input.set_default_cursor_shape(Input.CURSOR_DRAG)
|
||||
card.mouse_offset = card.get_global_mouse_position() - card.global_position
|
||||
if Input.is_action_just_released("SELECT"):
|
||||
card.dragging = false
|
||||
card.check_hover()
|
||||
|
83
scenes/card/load.gd
Normal file
83
scenes/card/load.gd
Normal file
@ -0,0 +1,83 @@
|
||||
extends Node
|
||||
|
||||
var card: Node
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
card = get_parent()
|
||||
|
||||
if _load_card() != OK:
|
||||
# TODO: No need to push another error as the failure state of loading does that already,
|
||||
# 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.")
|
||||
|
||||
|
||||
func _load_card() -> Error:
|
||||
if _load_data() != OK:
|
||||
return FAILED
|
||||
|
||||
if _load_image() != OK:
|
||||
return FAILED
|
||||
|
||||
return OK
|
||||
|
||||
|
||||
func _load_data() -> Error:
|
||||
var cached_json = FileAccess.get_file_as_string(
|
||||
"user://card_cache/" + card.card_info["id"] + "/card.json"
|
||||
)
|
||||
|
||||
if cached_json.is_empty():
|
||||
push_error("%s\nCard json data was not found in cache" % card.error("CACHE"))
|
||||
return FAILED
|
||||
|
||||
var card_json = JSON.parse_string(cached_json)
|
||||
|
||||
if card_json == null:
|
||||
push_error("%s\nCard json data is could not be parsed as valid json" % card.error("DATA"))
|
||||
return FAILED
|
||||
|
||||
card.card_info["name"] = card_json["name"]
|
||||
card.card_info["type"] = card_json["type_line"]
|
||||
card.card_info["desc"] = card_json["oracle_text"]
|
||||
card.card_info["cost"] = card_json["mana_cost"]
|
||||
|
||||
return OK
|
||||
|
||||
|
||||
func _load_image() -> Error:
|
||||
var cached_img = FileAccess.get_file_as_bytes(
|
||||
"user://card_cache/" + card.card_info["id"] + "/card.png"
|
||||
)
|
||||
|
||||
if cached_img.is_empty():
|
||||
push_error("%sCard on-board image was not found in cache" % card.error("CACHE"))
|
||||
return FAILED
|
||||
|
||||
var cache_image = Image.new()
|
||||
var image_status: Error = cache_image.load_png_from_buffer(cached_img)
|
||||
|
||||
if image_status != OK:
|
||||
push_error("%sCard on-board image failed to load correctly" % card.error("IMAGE"))
|
||||
return FAILED
|
||||
|
||||
card.cached_image = cache_image
|
||||
|
||||
var image = Image.new()
|
||||
image_status = image.load_png_from_buffer(cached_img)
|
||||
|
||||
if image_status != OK:
|
||||
push_error("%sCard on-board image failed to load correctly" % card.error("IMAGE"))
|
||||
return FAILED
|
||||
|
||||
var size = card.colission_size()
|
||||
image.resize(int(size.x), int(size.y), Image.INTERPOLATE_LANCZOS)
|
||||
|
||||
var image_texture = ImageTexture.new()
|
||||
image_texture.set_image(image)
|
||||
|
||||
var card_sprite = card.get_node("Sprite2D")
|
||||
card_sprite.texture = image_texture
|
||||
|
||||
return OK
|
1
scenes/card/load.gd.uid
Normal file
1
scenes/card/load.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://vckbno504iay
|
@ -4,19 +4,32 @@ extends Node
|
||||
@export var tap_speed = 5.0
|
||||
@export var scale_speed = 0.1
|
||||
|
||||
var card: Node
|
||||
|
||||
# TODO: Figure out elastic tween transitions for bounciness.
|
||||
|
||||
|
||||
func handle_constant_tweens(delta: float) -> void:
|
||||
if card.dragging:
|
||||
move_to(card.get_global_mouse_position() - card.mouse_offset, delta)
|
||||
|
||||
|
||||
func move_to(location: Vector2, delta: float) -> void:
|
||||
var tween = create_tween()
|
||||
tween.tween_property(get_parent(), "position", location, delta * move_speed)
|
||||
tween.tween_property(card, "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)
|
||||
tween.tween_property(card, "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)
|
||||
tween.tween_property(card, "scale", new_scale, scale_speed)
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
card = get_parent()
|
||||
|
17
scenes/tooltip/card_image.gd
Normal file
17
scenes/tooltip/card_image.gd
Normal file
@ -0,0 +1,17 @@
|
||||
extends TextureRect
|
||||
|
||||
|
||||
func _set_tip_image(_card_info: Dictionary, card_image: Image) -> void:
|
||||
card_image.resize(int(size.x / 1.75), int(size.y), Image.INTERPOLATE_LANCZOS)
|
||||
var tex = ImageTexture.new()
|
||||
tex.set_image(card_image)
|
||||
texture = tex
|
||||
|
||||
|
||||
func _clear_tip_image() -> void:
|
||||
texture = null
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
EventBus.connect("card_on_hover", _set_tip_image)
|
||||
EventBus.connect("card_on_unhover", _clear_tip_image)
|
1
scenes/tooltip/card_image.gd.uid
Normal file
1
scenes/tooltip/card_image.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://cpvbftm0swoa6
|
39
scenes/tooltip/card_text.gd
Normal file
39
scenes/tooltip/card_text.gd
Normal file
@ -0,0 +1,39 @@
|
||||
extends RichTextLabel
|
||||
|
||||
var mana_symbols: Dictionary
|
||||
|
||||
func _convert_text_to_symbol(_text: String):
|
||||
var last_idx = 0
|
||||
for symbol in mana_symbols:
|
||||
last_idx = 0
|
||||
while _text.find(symbol, last_idx) != -1:
|
||||
_text = _text.replace(symbol, "[img]" + mana_symbols[symbol] + "[/img]")
|
||||
last_idx = _text.find(symbol, last_idx) + symbol.length()
|
||||
return _text
|
||||
|
||||
|
||||
func _set_tip_text(card_info: Dictionary, _card_image: Image) -> void:
|
||||
# TODO: add more card formatting, check all of the logos, very niche icons will be affected i believe since they're
|
||||
# different sizes
|
||||
# shrink text if we use too much space for it, etc
|
||||
text = "[b]" + card_info["name"] + "[/b]\t"
|
||||
text += _convert_text_to_symbol(card_info["cost"]) + "\n"
|
||||
text += "[i]" + card_info["type"] + "[/i]\n"
|
||||
|
||||
text += _convert_text_to_symbol(card_info["desc"])
|
||||
|
||||
|
||||
func _clear_tip_text() -> void:
|
||||
text = ""
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if !FileAccess.file_exists("res://symbol_cache/symbols.json"):
|
||||
push_error("Symbols haven't been cached yet!")
|
||||
return
|
||||
var file = FileAccess.open("res://symbol_cache/symbols.json", FileAccess.READ)
|
||||
mana_symbols = JSON.parse_string(file.get_as_text())
|
||||
file.close()
|
||||
|
||||
EventBus.connect("card_on_hover", _set_tip_text)
|
||||
EventBus.connect("card_on_unhover", _clear_tip_text)
|
1
scenes/tooltip/card_text.gd.uid
Normal file
1
scenes/tooltip/card_text.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://b8tioen4n1rip
|
@ -109,19 +109,15 @@ func _ready() -> void:
|
||||
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.
|
||||
|
||||
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
|
@ -1,6 +1,8 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://b4ldtb3gw0jlu"]
|
||||
[gd_scene load_steps=7 format=3 uid="uid://b4ldtb3gw0jlu"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cfkew150yl1y3" path="res://tabletop.gd" id="1_3we3x"]
|
||||
[ext_resource type="Script" uid="uid://b8tioen4n1rip" path="res://scenes/tooltip/card_text.gd" id="2_d43bn"]
|
||||
[ext_resource type="Script" uid="uid://cpvbftm0swoa6" path="res://scenes/tooltip/card_image.gd" id="2_pqag1"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_3we3x"]
|
||||
bg_color = Color(0, 0, 0, 1)
|
||||
@ -35,6 +37,23 @@ theme_override_constants/separation = 0
|
||||
custom_minimum_size = Vector2(0, 540)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="UI/BigBar/Items/MenuArea"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="UI/BigBar/Items/MenuArea/VBoxContainer"]
|
||||
custom_minimum_size = Vector2(400, 300)
|
||||
layout_direction = 2
|
||||
layout_mode = 2
|
||||
stretch_mode = 5
|
||||
script = ExtResource("2_pqag1")
|
||||
|
||||
[node name="RichTextLabel" type="RichTextLabel" parent="UI/BigBar/Items/MenuArea/VBoxContainer"]
|
||||
custom_minimum_size = Vector2(0, 230)
|
||||
layout_mode = 2
|
||||
bbcode_enabled = true
|
||||
fit_content = true
|
||||
script = ExtResource("2_d43bn")
|
||||
|
||||
[node name="ChatArea" type="PanelContainer" parent="UI/BigBar/Items"]
|
||||
custom_minimum_size = Vector2(0, 270)
|
||||
layout_mode = 2
|
||||
|
Reference in New Issue
Block a user