From 029ad6d45fc9114e2aa15105918833592bc12f84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+GerardGascon@users.noreply.github.com> Date: Wed, 9 Apr 2025 16:49:50 +0200 Subject: [PATCH] feat: ability to share dragons --- scenes/dragon_adder.gd | 22 +++++++++ scenes/dragon_adder.gd.uid | 1 + scenes/dragon_adder/dragon_adder.gd | 35 ++++++++++++++ scenes/dragon_adder/dragon_adder.gd.uid | 1 + scenes/dragon_adder/dragon_adder.tscn | 62 +++++++++++++++++++++++++ scenes/dragon_list/dragon_list_view.gd | 2 +- scenes/dragons/dragon_entity_dragger.gd | 6 ++- scenes/main.gd | 34 ++++++++++---- scenes/main.tscn | 18 ++++++- scenes/window/dragon.gd | 7 +-- scenes/window/dragon_popup.tscn | 3 +- src/dragon_code_generator.gd | 4 ++ src/dragon_instantiator.gd | 16 +++++-- src/dragon_library.gd | 16 +++++-- src/save_load.gd | 6 +-- 15 files changed, 203 insertions(+), 30 deletions(-) create mode 100644 scenes/dragon_adder.gd create mode 100644 scenes/dragon_adder.gd.uid create mode 100644 scenes/dragon_adder/dragon_adder.gd create mode 100644 scenes/dragon_adder/dragon_adder.gd.uid create mode 100644 scenes/dragon_adder/dragon_adder.tscn diff --git a/scenes/dragon_adder.gd b/scenes/dragon_adder.gd new file mode 100644 index 0000000..1116a4f --- /dev/null +++ b/scenes/dragon_adder.gd @@ -0,0 +1,22 @@ +extends Button + + +@export var dragon_adder: PackedScene +@onready var base: GameManager = $"../.." + + +func _on_pressed() -> void: + var adder: DragonAdder = dragon_adder.instantiate() + adder.dragon_added.connect(_add_dragon) + + var window_position: Vector2i = DisplayServer.window_get_position() + var window_size: Vector2i = DisplayServer.window_get_size() + + adder.position = window_position - adder.size / 2 + + adder.show() + add_child(adder) + + +func _add_dragon(dragon_name: String, hat: Texture2D, shirt: Texture2D, shoes: Texture2D): + base.add_dragon(hat, shirt, shoes, dragon_name) diff --git a/scenes/dragon_adder.gd.uid b/scenes/dragon_adder.gd.uid new file mode 100644 index 0000000..a510bd2 --- /dev/null +++ b/scenes/dragon_adder.gd.uid @@ -0,0 +1 @@ +uid://w60u0tg1hlvu diff --git a/scenes/dragon_adder/dragon_adder.gd b/scenes/dragon_adder/dragon_adder.gd new file mode 100644 index 0000000..5decaf1 --- /dev/null +++ b/scenes/dragon_adder/dragon_adder.gd @@ -0,0 +1,35 @@ +extends Window +class_name DragonAdder + + +@export var hat_outfits: DragonOutfit +@export var shirt_outfits: DragonOutfit +@export var shoes_outfits: DragonOutfit + +var code_generator: CodeGenerator + +@onready var line_edit: LineEdit = $CanvasLayer/LineEdit + +signal dragon_added(dragon_name: String, hat: Texture2D, shirt: Texture2D, shoes: Texture2D) + + +func _ready() -> void: + code_generator = CodeGenerator.new(hat_outfits, shirt_outfits, shoes_outfits) + + +func _on_button_pressed() -> void: + var dragon: Dictionary = code_generator.descrypt(line_edit.text) + if dragon['name'] == null: + return + + var name: String = dragon['name'] + var hat: Texture2D = dragon['hat'] + var shirt: Texture2D = dragon['shirt'] + var shoes: Texture2D = dragon['shoes'] + + dragon_added.emit(name, hat, shirt, shoes) + + queue_free() + +func _on_close_requested() -> void: + queue_free() diff --git a/scenes/dragon_adder/dragon_adder.gd.uid b/scenes/dragon_adder/dragon_adder.gd.uid new file mode 100644 index 0000000..839e749 --- /dev/null +++ b/scenes/dragon_adder/dragon_adder.gd.uid @@ -0,0 +1 @@ +uid://b1fnwy6wnufw1 diff --git a/scenes/dragon_adder/dragon_adder.tscn b/scenes/dragon_adder/dragon_adder.tscn new file mode 100644 index 0000000..c0d2b3c --- /dev/null +++ b/scenes/dragon_adder/dragon_adder.tscn @@ -0,0 +1,62 @@ +[gd_scene load_steps=6 format=3 uid="uid://oqa2ry73vqjf"] + +[ext_resource type="Script" uid="uid://b1fnwy6wnufw1" path="res://scenes/dragon_adder/dragon_adder.gd" id="1_x83p2"] +[ext_resource type="Resource" uid="uid://cnhwn6kfcbjl5" path="res://assets/outfits/hats.tres" id="2_33u3u"] +[ext_resource type="Script" uid="uid://mhudiyt5gnt1" path="res://scenes/dragon_editor/line_edit.gd" id="2_77mmq"] +[ext_resource type="Resource" uid="uid://etegcak2sphs" path="res://assets/outfits/shirts.tres" id="3_xb0i6"] +[ext_resource type="Resource" uid="uid://ba5684xylts3f" path="res://assets/outfits/shoes.tres" id="4_nf61g"] + +[node name="DragonAdder" type="Window"] +position = Vector2i(0, 36) +size = Vector2i(500, 300) +transient = true +exclusive = true +script = ExtResource("1_x83p2") +hat_outfits = ExtResource("2_33u3u") +shirt_outfits = ExtResource("3_xb0i6") +shoes_outfits = ExtResource("4_nf61g") + +[node name="CanvasLayer" type="CanvasLayer" parent="."] + +[node name="Button" type="Button" parent="CanvasLayer"] +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -32.0 +offset_top = -31.0 +offset_right = 32.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "afegeix" + +[node name="LineEdit" type="LineEdit" parent="CanvasLayer"] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -214.0 +offset_top = -29.0 +offset_right = 214.0 +offset_bottom = 29.0 +grow_horizontal = 2 +grow_vertical = 2 +placeholder_text = "CODI" +alignment = 1 +max_length = 22 +script = ExtResource("2_77mmq") + +[node name="Label" type="Label" parent="CanvasLayer"] +anchors_preset = 5 +anchor_left = 0.5 +anchor_right = 0.5 +offset_left = -59.5 +offset_right = 59.5 +offset_bottom = 23.0 +grow_horizontal = 2 +text = "afegeix un drac" + +[connection signal="close_requested" from="." to="." method="_on_close_requested"] +[connection signal="pressed" from="CanvasLayer/Button" to="." method="_on_button_pressed"] diff --git a/scenes/dragon_list/dragon_list_view.gd b/scenes/dragon_list/dragon_list_view.gd index 7bfccaf..0dbbd29 100644 --- a/scenes/dragon_list/dragon_list_view.gd +++ b/scenes/dragon_list/dragon_list_view.gd @@ -18,7 +18,7 @@ func set_library(library: DragonLibrary): var shirt: Texture2D = shirt_outfits.get_texture(d['shirt']) var shoes: Texture2D = shoes_outfits.get_texture(d['shoes']) append_dragon(d['name'], hat, shirt, shoes) - +# func append_dragon(name: String, hat: Texture2D, shirt: Texture2D, shoes: Texture2D): var dragon: DragonListEntry = dragon_list_entry.instantiate() diff --git a/scenes/dragons/dragon_entity_dragger.gd b/scenes/dragons/dragon_entity_dragger.gd index 04fe1ff..9acd70d 100644 --- a/scenes/dragons/dragon_entity_dragger.gd +++ b/scenes/dragons/dragon_entity_dragger.gd @@ -4,7 +4,9 @@ class_name DragonEntity @export var dragon: DragonSprite -signal on_pick(position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String) +signal on_pick(dragon_id: int, position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String) + +var id: int func _ready() -> void: @@ -15,7 +17,7 @@ func _input_event(viewport, event, shape_idx) -> void: if event is InputEventMouseButton \ and event.button_index == MOUSE_BUTTON_LEFT \ and event.is_pressed(): - on_pick.emit(position, dragon.hat.texture, dragon.shirt.texture, dragon.shoes.texture, dragon.name_label.text) + on_pick.emit(id, position, dragon.hat.texture, dragon.shirt.texture, dragon.shoes.texture, dragon.name_label.text) queue_free() diff --git a/scenes/main.gd b/scenes/main.gd index 8f0fefe..91f788c 100644 --- a/scenes/main.gd +++ b/scenes/main.gd @@ -14,16 +14,17 @@ var _instantiator: DragonInstantiator var _save_load: SaveLoad var _library: DragonLibrary +var _dragon_entities: Dictionary = {} + func _ready(): _library = DragonLibrary.new(hat_outfits, shirt_outfits, shoes_outfits) _instantiator = DragonInstantiator.new(dragon_template, get_viewport(), get_window()) - _save_load = SaveLoad.new() - _load_game() await get_tree().process_frame move_window_to_bottom_right() + _load_game() func move_window_to_bottom_right(): @@ -42,39 +43,52 @@ func move_window_to_bottom_right(): func add_dragon(hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String): # TODO: Check for free positon - _instantiate_dragon_ingame(dragon_spots[0].position, hat, shirt, shoes, dragon_name) - _library.add_dragon(dragon_name, hat, shirt, shoes) + var id: int = _library.add_dragon(dragon_name, hat, shirt, shoes) + _instantiate_dragon_ingame(dragon_spots[0].position, hat, shirt, shoes, dragon_name, id) func _load_game(): _save_load.load() - _library.add_dragons(_save_load.get_dragons()) + var dragons: Array = _save_load.get_dragons() + _library.add_dragons(dragons) + for d in dragons: + if d['pos'] != Vector2i(0, 0): + var hat: Texture2D = hat_outfits.get_texture(d['hat']) + var shirt: Texture2D = shirt_outfits.get_texture(d['shirt']) + var shoes: Texture2D = shoes_outfits.get_texture(d['shoes']) + _pick_dragon(d['id'], d['pos'], hat, shirt, shoes, d['name'], false) print(_save_load.contents_to_save) -func _instantiate_dragon_ingame(position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String): +func _instantiate_dragon_ingame(position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String, id: int): var dragon: DragonEntity = dragon_ingame.instantiate() dragon.dress(hat, shirt, shoes) dragon.set_dragon_name(dragon_name) add_child(dragon) + dragon.id = id dragon.position = position dragon.on_pick.connect(_pick_dragon) -func _pick_dragon(position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String): - var dragon: Dragon = _instantiator.instantiate(position, hat, shirt, shoes, dragon_name) +func _pick_dragon(id: int, position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String, drag: bool = true): + var dragon: Dragon = _instantiator.instantiate(position, hat, shirt, shoes, dragon_name, drag) + dragon.id = id + _dragon_entities[id] = dragon dragon.place_back.connect(_dragon_place_back) add_child(dragon) func _dragon_place_back(dragon: Dragon): - print(dragon) + _dragon_entities.erase(dragon.id) func _on_close_pressed() -> void: _save_load.clear_dragons() for d in _library.dragons: - _save_load.add_dragon(d['name'], d['hat'], d['shirt'], d['shoes']) + if _dragon_entities.has(d['id']) and _dragon_entities[d['id']] != null: + _save_load.add_dragon(d['id'], d['name'], d['hat'], d['shirt'], d['shoes'], _dragon_entities[d['id']].position) + else: + _save_load.add_dragon(d['id'], d['name'], d['hat'], d['shirt'], d['shoes'], Vector2i(0, 0)) _save_load.save() await get_tree().process_frame await get_tree().process_frame diff --git a/scenes/main.tscn b/scenes/main.tscn index 8013a04..6218a99 100644 --- a/scenes/main.tscn +++ b/scenes/main.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=12 format=3 uid="uid://ctytpqaed0yqx"] +[gd_scene load_steps=14 format=3 uid="uid://ctytpqaed0yqx"] [ext_resource type="Script" uid="uid://3kyt3shje5r1" path="res://scenes/main.gd" id="1_sugp2"] [ext_resource type="PackedScene" uid="uid://c7nfcgjxqeg7l" path="res://scenes/window/dragon_popup.tscn" id="2_jyhfs"] @@ -11,6 +11,8 @@ [ext_resource type="Resource" uid="uid://ba5684xylts3f" path="res://assets/outfits/shoes.tres" id="6_ya4ey"] [ext_resource type="Script" uid="uid://oc6mw86npbii" path="res://scenes/list_button.gd" id="9_choun"] [ext_resource type="PackedScene" uid="uid://tubxrqxjic6r" path="res://scenes/dragon_list/dragon_list.tscn" id="10_ya4ey"] +[ext_resource type="Script" uid="uid://w60u0tg1hlvu" path="res://scenes/dragon_adder.gd" id="11_eb6dy"] +[ext_resource type="PackedScene" uid="uid://oqa2ry73vqjf" path="res://scenes/dragon_adder/dragon_adder.tscn" id="12_trceg"] [node name="Base" type="Node2D" node_paths=PackedStringArray("dragon_spots")] script = ExtResource("1_sugp2") @@ -60,6 +62,19 @@ text = "llista" script = ExtResource("9_choun") dragon_list = ExtResource("10_ya4ey") +[node name="Adder" type="Button" parent="CanvasLayer"] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -156.0 +offset_top = 407.0 +offset_right = -56.0 +offset_bottom = 507.0 +grow_horizontal = 0 +text = "afegeix" +script = ExtResource("11_eb6dy") +dragon_adder = ExtResource("12_trceg") + [node name="Icon" type="Sprite2D" parent="."] position = Vector2(576, 324) scale = Vector2(9, 5.0625) @@ -79,3 +94,4 @@ position = Vector2(850, 360) [connection signal="button_up" from="CanvasLayer/Create" to="CanvasLayer/Create" method="_on_button_up"] [connection signal="pressed" from="CanvasLayer/Close" to="." method="_on_close_pressed"] [connection signal="pressed" from="CanvasLayer/List" to="CanvasLayer/List" method="_on_pressed"] +[connection signal="pressed" from="CanvasLayer/Adder" to="CanvasLayer/Adder" method="_on_pressed"] diff --git a/scenes/window/dragon.gd b/scenes/window/dragon.gd index 6934233..c70060d 100644 --- a/scenes/window/dragon.gd +++ b/scenes/window/dragon.gd @@ -6,7 +6,7 @@ class_name Dragon @onready var _actual_position: Vector2 = position var main_window_rect: Rect2i -@onready var draggable: Draggable = $DragDropDetector +@export var draggable: Draggable var _walking: bool = false var _thinking_path: bool = false @@ -15,15 +15,16 @@ var rng: RandomNumberGenerator = RandomNumberGenerator.new() signal place_back(dragon: Dragon) +var id: int + func on_place_back() -> void: place_back.emit(self) -func _ready() -> void: +func start_dragon_drag()-> void: draggable.initial_drag() - func _process(delta: float) -> void: if draggable.dragging: _actual_position = position diff --git a/scenes/window/dragon_popup.tscn b/scenes/window/dragon_popup.tscn index 6979d4e..34415e6 100644 --- a/scenes/window/dragon_popup.tscn +++ b/scenes/window/dragon_popup.tscn @@ -4,7 +4,7 @@ [ext_resource type="Script" uid="uid://ch7d3wo8ucskb" path="res://scenes/window/draggable.gd" id="2_2r6si"] [ext_resource type="PackedScene" uid="uid://baa8gpicw2yg0" path="res://scenes/dragons/dragon_sprite.tscn" id="3_ctdir"] -[node name="DragonPopup" type="Window" node_paths=PackedStringArray("dragon")] +[node name="DragonPopup" type="Window" node_paths=PackedStringArray("dragon", "draggable")] disable_3d = true transparent_bg = true size = Vector2i(128, 128) @@ -14,6 +14,7 @@ transparent = true script = ExtResource("1_ctdir") dragon_speed = 100.0 dragon = NodePath("Dragon") +draggable = NodePath("DragDropDetector") [node name="DragDropDetector" type="Control" parent="."] layout_mode = 3 diff --git a/src/dragon_code_generator.gd b/src/dragon_code_generator.gd index c857bbc..f84d613 100644 --- a/src/dragon_code_generator.gd +++ b/src/dragon_code_generator.gd @@ -115,6 +115,8 @@ func _char_to_bin(character: String) -> String: func _bin_to_char(character: String) -> String: + if not alphabet_inverse.has(character): + return "" return alphabet_inverse[character] @@ -136,6 +138,8 @@ func read_code(code: String) -> Dictionary: for i in range(code.substr(6).length()): if i % 2 != 0: continue + if _bin_to_char(code.substr(6 + i, 2)) == "": + return {'hat': null, 'shirt': null, 'shoes': null, 'name': null} name += _bin_to_char(code.substr(6 + i, 2)) return {'hat': hat, 'shirt': shirt, 'shoes': shoes, 'name': name} diff --git a/src/dragon_instantiator.gd b/src/dragon_instantiator.gd index cd6bd6d..477ae5c 100644 --- a/src/dragon_instantiator.gd +++ b/src/dragon_instantiator.gd @@ -10,9 +10,11 @@ func _init(dragon: PackedScene, viewport: Viewport, window: Window) -> void: _dragon_template = dragon -func instantiate(position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String) -> Node: +func instantiate(position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String, drag: bool) -> Node: + if drag == false: + return _instantiate_dragon(position, hat, shirt, shoes, dragon_name, drag) var relative_position: Vector2i = _calculate_relative_position(position) - return _instantiate_dragon(relative_position, hat, shirt, shoes, dragon_name) + return _instantiate_dragon(relative_position, hat, shirt, shoes, dragon_name, drag) func _calculate_window_scale() -> Vector2: @@ -27,13 +29,16 @@ func _calculate_relative_position(position: Vector2) -> Vector2i: return Vector2i(Vector2(position) * scale) -func _instantiate_dragon(relative_position: Vector2i, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String) -> Node: +func _instantiate_dragon(relative_position: Vector2i, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String, drag: bool) -> Node: var dragon: Dragon = _dragon_template.instantiate() var window_position: Vector2i = DisplayServer.window_get_position() var window_size: Vector2i = DisplayServer.window_get_size() - dragon.position = window_position + relative_position - dragon.size / 2 + if drag == false: + dragon.position = relative_position + else: + dragon.position = window_position + relative_position - dragon.size / 2 dragon.dress(hat, shirt, shoes) dragon.set_dragon_name(dragon_name) @@ -42,4 +47,7 @@ func _instantiate_dragon(relative_position: Vector2i, hat: Texture2D, shirt: Tex dragon.main_window_rect = Rect2i(window_position, window_size) dragon.show() + if drag: + dragon.start_dragon_drag() + return dragon diff --git a/src/dragon_library.gd b/src/dragon_library.gd index 2032475..401723e 100644 --- a/src/dragon_library.gd +++ b/src/dragon_library.gd @@ -15,15 +15,21 @@ func _init(hat_outfits: DragonOutfit, shirt_outfits: DragonOutfit, shoes_outfits self.shoes_outfits = shoes_outfits -func add_dragon(name: String, hat: Texture2D, shirt: Texture2D, shoes: Texture2D): +func add_dragon(name: String, hat: Texture2D, shirt: Texture2D, shoes: Texture2D) -> int: var hat_index: int = hat_outfits.get_index(hat) var shirt_index: int = shirt_outfits.get_index(shirt) var shoes_index: int = shoes_outfits.get_index(shoes) - dragons.push_back({'name': name, 'hat': hat_index, 'shirt': shirt_index, 'shoes': shoes_index}) + var id: int = RandomNumberGenerator.new().randi() + _push_dragon(id, name, hat_index, shirt_index, shoes_index) + return id func add_dragons(dragons: Array) -> void: for d in dragons: - self.dragons.push_back( - {'name': d['name'], 'hat': d['hat'], 'shirt': d['shirt'], 'shoes': d['shoes']} - ) + _push_dragon(d['id'], d['name'], d['hat'], d['shirt'], d['shoes']) + + +func _push_dragon(id: int, name: String, hat: int, shirt: int, shoes: int): + dragons.push_back( + {'id': id, 'name': name, 'hat': hat, 'shirt': shirt, 'shoes': shoes} + ) diff --git a/src/save_load.gd b/src/save_load.gd index de16e0d..5ef2728 100644 --- a/src/save_load.gd +++ b/src/save_load.gd @@ -1,7 +1,7 @@ class_name SaveLoad -const save_location = "user://save.json" +const save_location = "user://save.data" var contents_to_save: Dictionary = { @@ -40,8 +40,8 @@ func clear_dragons() -> void: contents_to_save['dragons'] = [] -func add_dragon(name: String, hat: int, shirt: int, shoes: int) -> void: - contents_to_save['dragons'].push_back({'name': name, 'hat': hat, 'shirt': shirt, 'shoes': shoes}) +func add_dragon(id: int, name: String, hat: int, shirt: int, shoes: int, pos: Vector2i) -> void: + contents_to_save['dragons'].push_back({'id': id, 'name': name, 'hat': hat, 'shirt': shirt, 'shoes': shoes, 'pos': pos}) func get_dragons() -> Array: