From a6650e614011e7656f21f5e1e22936bcedc4bf16 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Fri, 13 Oct 2023 02:04:43 +0200 Subject: [PATCH] Sort some things with the shop but I'm not sure what the error currently means --- game/game.gd | 5 ++- game/shop_item.gd | 15 ++++++++- game/shop_item.tscn | 6 ++++ interface/ghost/ghost.gd | 55 +++++++++++++++++++++++++------- interface/ghost/ghost.tscn | 6 +--- interface/ghost/overlap_freer.gd | 12 ++++--- interface/purchasable_item.gd | 12 +++---- interface/shop_ui.gd | 10 +++--- 8 files changed, 85 insertions(+), 36 deletions(-) create mode 100644 game/shop_item.tscn diff --git a/game/game.gd b/game/game.gd index eb71316..696d604 100644 --- a/game/game.gd +++ b/game/game.gd @@ -88,9 +88,8 @@ func update_counter_icon(): else: store_collector_texturerect.texture = null -func _on_ghost_requested(scene: PackedScene, texture: Texture2D): - ghost.scene_to_instantiate = scene - ghost.preview_texture = texture +func _on_ghost_requested(item: PurchasableItem): + ghost.COMPAT_set_to_purchasable_item(item) ghost.process_mode = Node.PROCESS_MODE_INHERIT ghost.show() diff --git a/game/shop_item.gd b/game/shop_item.gd index de5aea8..5187dac 100644 --- a/game/shop_item.gd +++ b/game/shop_item.gd @@ -14,7 +14,7 @@ class_name ShopItem ## The item type to collect to purchase the item. ## ## If null, counts the items' value. -@export var cost_tag: StringPath +@export var cost_tag: StringName ## The quantity of items to collect to purchase the item. ## @@ -24,8 +24,21 @@ class_name ShopItem ## The shape that the ghost should use to determine if the item's placement is valid. ## ## Concave shapes might have problems interacting with the placeable area. +## +## May be null if the purchase does not involve the placement of an item. @export var placement_shape: Shape2D +## The texture that should be rendered when the ghost is placing this item. +## +## Will be made transparent and modulated to red by the ghost. +## +## May be null if the purchase does not involve the placement of an item. +@export var placement_texture: Texture2D + +## The scene to instantiate when the purchase is complete. +## +## May be null if the purchase does not involve the placement of an item. +@export var placement_scene: PackedScene ## What to do when this item is purchased. signal on_purchase diff --git a/game/shop_item.tscn b/game/shop_item.tscn new file mode 100644 index 0000000..8185cc6 --- /dev/null +++ b/game/shop_item.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://ct4sh7f8qnyob"] + +[ext_resource type="Script" path="res://game/shop_item.gd" id="1_8e5vp"] + +[node name="ShopItem" type="Node"] +script = ExtResource("1_8e5vp") diff --git a/interface/ghost/ghost.gd b/interface/ghost/ghost.gd index 0b418ca..2c407c9 100644 --- a/interface/ghost/ghost.gd +++ b/interface/ghost/ghost.gd @@ -30,34 +30,65 @@ class_name Ghost ## The [Sprite2D] node previewing the scene. @onready var preview_sprite: Sprite2D = $PlacementShape/PreviewSprite +## The position the ghost should have when a new body starts being placed. +@onready var starting_position: Vector2 = position -var can_place: bool = false +## The rotation the ghost should have when a new body starts being placed. +@onready var starting_rotation_radians: float = rotation + + +## Whether this object can currently be placed. +var can_place: bool = false: + get: + return can_place + set(value): + if value != can_place: + can_place_changed.emit(value) + can_place = value + modulate = valid_color if value else invalid_color + +## Emitted when [can_place] changes value. +signal can_place_changed(to: bool) func _ready(): # Initialize the Area's collision mask - collision_mask = overlap_checker.collision_mask | placeable_area_checker.collision_mask | overlap_freer.collision_mask - + collision_mask = overlap_checker.overlap_mask | placeable_area_checker.overlap_mask | overlap_freer.overlap_mask ## Update the value of [can_place]. func update_state(): # DIRTY HACK: Relies on the placeable area being perfectly surrounded by solid bodies. can_place = overlap_checker.is_overlapping_with == null and placeable_area_checker.is_overlapping_with != null +## For retro-compatibility, configure this for the placement of a [PurchasableItem]. +func COMPAT_set_to_purchasable_item(pi: PurchasableItem): + instantiator.scene_to_instantiate = pi.item_scene + placement_shape.shape = pi.get_node("ConverterPlacementBody").get_node("FullConverterShape").shape + placement_shape.scale = pi.item_scene.scale + preview_sprite.texture = pi.item_icon + position = starting_position + rotation = starting_rotation_radians + +## Configure this for the placement of a [ShopItem]. func set_to_shop_item(si: ShopItem): - pass + instantiator.scene_to_instantiate = si.placement_scene + placement_shape.shape = si.placement_shape # TODO: Hmmm. Not the best interface. + placement_shape.scale = si.placement_scene.scale + preview_sprite.texture = si.placement_texture + position = starting_position + rotation = starting_rotation_radians +## Emitted when [materialize] is called. +signal materialized(what: Node) -func materialize(): - # Compatibility stub for Instantiator +## Try to materialize the scene, returning it if the instantiation was successful, or null if it wasn't. +## +## Remember to try the placement again if this returns null! +func materialize() -> Node: if not can_place: return null - var overlapping_bodies = get_overlapping_bodies() - for body in overlapping_bodies: - if body is PhysicsBody2D: - if body.collision_layer & collision_mask_delete_placement: - body.queue_free() + overlap_freer.area_queue_free() var inst = instantiator.instantiate() - # TODO: Remove this + materialized.emit(inst) return inst diff --git a/interface/ghost/ghost.tscn b/interface/ghost/ghost.tscn index b66079b..dbb4e25 100644 --- a/interface/ghost/ghost.tscn +++ b/interface/ghost/ghost.tscn @@ -13,13 +13,9 @@ collision_layer = 0 collision_mask = 4294967295 input_pickable = false script = ExtResource("1_1bq64") -valid_color = null -invalid_color = null -collision_mask_prevent_placement = 16 -collision_mask_delete_placement = 4 [node name="PlacementShape" parent="." instance=ExtResource("2_bo8dp")] -scale = Vector2(2.5, 2.5) +shape = null [node name="PreviewSprite" type="Sprite2D" parent="PlacementShape"] modulate = Color(1, 1, 1, 0.5) diff --git a/interface/ghost/overlap_freer.gd b/interface/ghost/overlap_freer.gd index a237054..afdeefa 100644 --- a/interface/ghost/overlap_freer.gd +++ b/interface/ghost/overlap_freer.gd @@ -28,10 +28,14 @@ func get_all_overlapping_bodies() -> Array[Node2D]: return bodies ## Emitted when a body is about to be [queue_free]d. -signal body_queueing_free(body: Node2D) +signal queueing_free(body: Node2D) + +## Queue free the passed nodes. +func mass_queue_free(nodes: Array[Node2D]): + for node in nodes: + queueing_free.emit(node) + node.queue_free() ## Queue free all overlapping bodies. func area_queue_free() -> void: - for body in get_all_overlapping_bodies(): - body_queueing_free.emit(body) - body.queue_free() + mass_queue_free(get_all_overlapping_bodies()) diff --git a/interface/purchasable_item.gd b/interface/purchasable_item.gd index ac10bd2..1d326ab 100644 --- a/interface/purchasable_item.gd +++ b/interface/purchasable_item.gd @@ -90,25 +90,25 @@ var has_bought: bool: ## Emitted when a purchase has started. -signal purchase_begin +signal purchase_begin(what: PurchasableItem) ## Emitted when a purchase is cancelled. -signal purchase_cancel +signal purchase_cancel(what: PurchasableItem) ## Emitted when a purchase is completed. ## ## Emitted by complete_purchase(). -signal purchase_success +signal purchase_success(what: PurchasableItem) func _on_buy_button_pressed(): if is_buying: is_buying = false - purchase_cancel.emit() + purchase_cancel.emit(self) else: is_buying = true - purchase_begin.emit() + purchase_begin.emit(self) func complete_purchase(): is_buying = false - purchase_success.emit() + purchase_success.emit(self) diff --git a/interface/shop_ui.gd b/interface/shop_ui.gd index 49ea431..45cf411 100644 --- a/interface/shop_ui.gd +++ b/interface/shop_ui.gd @@ -23,14 +23,14 @@ signal purchase_success(what: PurchasableItem) ## Array of all PurchasableItems that this ShopUI should control. @onready var purchasable_items: Array[Node] = find_children("*", "PurchasableItem") -signal ghost_requested(scene: PackedScene, texture: Texture2D) +signal ghost_requested(what: PurchasableItem) func _ready(): for item in purchasable_items: - item.purchase_begin.connect(_on_any_purchase_begin.bind(item)) - item.purchase_cancel.connect(_on_any_purchase_cancel.bind(item)) - item.purchase_success.connect(_on_any_purchase_success.bind(item)) + item.purchase_begin.connect(_on_any_purchase_begin) + item.purchase_cancel.connect(_on_any_purchase_cancel) + item.purchase_success.connect(_on_any_purchase_success) func _on_any_purchase_begin(what: Node): if not what is PurchasableItem: @@ -38,7 +38,7 @@ func _on_any_purchase_begin(what: Node): return delete_button.disabled = true if what.item_scene: - ghost_requested.emit(what.item_scene, what.item_icon) + ghost_requested.emit(what) purchase_begin.emit(what) set_all_can_buy(false, what)