177 lines
4.3 KiB
GDScript
177 lines
4.3 KiB
GDScript
extends TextureRect
|
|
#extends Sprite2D
|
|
## 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
|
|
|
|
var card_id: String
|
|
var card_name: String
|
|
var card_type: String
|
|
var oracle_text: String
|
|
|
|
# Tween trackers for distinguishing which state the card is in.
|
|
var is_focused = false # Is the card a focus?
|
|
var is_dragging = false # Is the card currently being dragged?
|
|
var is_travelling = false # Is the card moving to a location?
|
|
var is_pivot = false # Is the card currently waiting to be tapped/untapped?
|
|
|
|
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:
|
|
_tweening(delta)
|
|
|
|
|
|
func _tweening(delta: float) -> void:
|
|
var tween = get_tree().create_tween()
|
|
|
|
if is_focused:
|
|
tween.tween_property(self, "scale", Vector2(1.05, 1.05), delta * delay)
|
|
else:
|
|
tween.tween_property(self, "scale", Vector2(1.0, 1.0), delta * delay)
|
|
|
|
if is_dragging:
|
|
tween.tween_property(
|
|
self, "position", get_global_mouse_position() - mouse_offset, delay * delta
|
|
)
|
|
|
|
if is_pivot:
|
|
tween.tween_property(self, "rotation_degrees", _pivot(), delta * delay)
|
|
is_pivot = false
|
|
|
|
|
|
func _gui_input(event: InputEvent) -> void:
|
|
if event is not InputEventMouseButton:
|
|
return
|
|
match event.button_index:
|
|
MOUSE_BUTTON_LEFT:
|
|
if event.pressed:
|
|
is_dragging = true
|
|
mouse_offset = get_global_mouse_position() - global_position
|
|
else:
|
|
is_dragging = false
|
|
MOUSE_BUTTON_RIGHT:
|
|
# TODO: Tooltip menu for right-button clicking on cards.
|
|
pass
|
|
|
|
|
|
func _on_mouse_entered() -> void:
|
|
is_focused = true
|
|
|
|
|
|
func _on_mouse_exited() -> void:
|
|
if not is_dragging:
|
|
is_focused = false
|
|
|
|
|
|
func travel_to(position: Vector2) -> Error:
|
|
# TODO: Check whether position to travel to is within the confines of where this card can go.
|
|
|
|
return OK
|
|
|
|
|
|
func _unhandled_key_input(event: InputEvent) -> void:
|
|
if not event.is_action_pressed("default_action"):
|
|
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)
|
|
|
|
|
|
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.")
|
|
|
|
set_pivot_offset(size / 2)
|
|
|
|
|
|
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
|
|
|
|
image.resize(int(size.x), int(size.y), Image.INTERPOLATE_LANCZOS)
|
|
|
|
var image_texture = ImageTexture.new()
|
|
image_texture.set_image(image)
|
|
|
|
texture = image_texture
|
|
|
|
return OK
|