1
Fork 0
mirror of https://github.com/Steffo99/swear-jar.git synced 2024-11-24 16:44:20 +00:00
swear-jar/interface/ghost/ghost.gd

139 lines
4.6 KiB
GDScript3
Raw Normal View History

2023-10-02 13:12:08 +00:00
extends Area2D
class_name Ghost
2023-10-02 15:53:13 +00:00
## Ghost previewing the instantiation of a scene.
2023-10-02 13:12:08 +00:00
2023-10-08 01:56:29 +00:00
## Color to modulate this with if the body currently isn't overlapping anything.
@export var valid_color: Color = Color.WHITE
## Color to modulate this with if the body currently is overlapping something.
@export var invalid_color: Color = Color.RED
## The [Instantiator] to use to spawn the ghosted item.
@onready var instantiator: Instantiator = $Instantiator
## The node which materialized entities should be attached to.
@export var container: Node = null:
get:
return instantiator.container
set(value):
instantiator.container = value
2023-10-08 01:56:29 +00:00
## The [OverlapChecker] to use to see if a solid block is overlapping the ghost.
@onready var overlap_checker: OverlapChecker = $OverlapChecker
## The [PlaceableAreaChecker] to use to see if the ghost is currently inside the placeable area.
@onready var placeable_area_checker: PlaceableAreaChecker = $PlaceableAreaChecker
## The [OverlapFreer] to use to delete the [PhysicsBody2D] behind the ghost before instantiation.
@onready var overlap_freer: OverlapFreer = $OverlapFreer
2023-10-02 15:53:13 +00:00
## The [CollisionShape2D] to use to check for placement checks.
##
## MUST consist of a [RectangleShape2D].
@onready var placement_shape: CollisionShape2D = $PlacementShape
2023-10-02 14:22:03 +00:00
2023-10-02 15:53:13 +00:00
## The [Sprite2D] node previewing the scene.
@onready var preview_sprite: Sprite2D = $PlacementShape/PreviewSprite
2023-10-02 14:22:03 +00:00
## The position the ghost should have when a new body starts being placed.
@onready var starting_position: Vector2 = position
2023-10-02 16:29:05 +00:00
## 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)
2023-10-02 14:22:03 +00:00
2023-10-05 22:09:24 +00:00
2023-10-02 16:29:05 +00:00
func _ready():
2023-10-12 19:45:52 +00:00
# Initialize the Area's collision mask
collision_mask = overlap_checker.overlap_mask | placeable_area_checker.overlap_mask | overlap_freer.overlap_mask
2023-10-02 16:29:05 +00:00
2023-10-08 01:56:29 +00:00
## Update the value of [can_place].
2023-10-12 19:45:52 +00:00
func update_state():
# DIRTY HACK: Relies on the placeable area being perfectly surrounded by solid bodies.
2023-10-08 01:56:29 +00:00
can_place = overlap_checker.is_overlapping_with == null and placeable_area_checker.is_overlapping_with != null
2023-10-02 16:29:05 +00:00
## For retro-compatibility, configure this for the placement of a [PurchasableItem].
func COMPAT_set_to_purchasable_item(pi: PurchasableItem):
2023-10-13 17:21:07 +00:00
push_warning("COMPAT_set_to_purchasable_item is deprecated.")
instantiator.scene_to_instantiate = pi.item_scene
2023-10-13 17:21:07 +00:00
var item_scene = pi.item_scene.instantiate()
placement_shape.shape = item_scene.get_node("ConverterPlacementBody/FullConverterShape").shape
placement_shape.scale = item_scene.scale
item_scene.queue_free()
preview_sprite.texture = pi.item_icon
position = starting_position
rotation = starting_rotation_radians
2023-10-13 17:21:07 +00:00
update_state()
2023-10-02 16:29:05 +00:00
## Configure this for the placement of a [ShopItem].
2023-10-12 19:45:52 +00:00
func set_to_shop_item(si: ShopItem):
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
2023-10-13 17:21:07 +00:00
update_state()
2023-10-12 19:45:52 +00:00
## Emitted when [materialize] is called.
signal materialized(what: Node)
2023-10-12 19:45:52 +00:00
## 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:
2023-10-02 18:28:08 +00:00
if not can_place:
return null
2023-10-13 17:21:07 +00:00
overlap_freer.update_is_overlapping_with()
overlap_freer.area_queue_free()
2023-10-08 01:56:29 +00:00
var inst = instantiator.instantiate()
materialized.emit(inst)
2023-10-08 01:56:29 +00:00
return inst
2023-10-13 17:21:07 +00:00
func _on_moved(_from, _to):
overlap_checker.update_is_overlapping_with()
overlap_freer.update_is_overlapping_with()
placeable_area_checker.update_is_overlapping_with()
2023-10-13 17:21:07 +00:00
update_state()
func _on_rotated_radians(_from, _to):
overlap_checker.update_is_overlapping_with()
overlap_freer.update_is_overlapping_with()
placeable_area_checker.update_is_overlapping_with()
update_state()
func _on_area_entered(_area):
placeable_area_checker.update_is_overlapping_with()
update_state()
func _on_area_exited(_area):
placeable_area_checker.update_is_overlapping_with()
update_state()
func _on_body_entered(_body):
overlap_checker.update_is_overlapping_with()
overlap_freer.update_is_overlapping_with()
update_state()
func _on_body_exited(_body):
overlap_checker.update_is_overlapping_with()
overlap_freer.update_is_overlapping_with()
2023-10-13 17:21:07 +00:00
update_state()