2025-07-07 15:59:22 +00:00
|
|
|
@tool
|
2025-06-30 10:33:40 +00:00
|
|
|
extends Node
|
|
|
|
|
2025-07-23 09:07:20 +00:00
|
|
|
|
2025-06-30 10:33:40 +00:00
|
|
|
#### Timer
|
|
|
|
func wait(duration: float) -> void:
|
2025-06-30 14:48:28 +00:00
|
|
|
if duration <= 0:
|
|
|
|
return
|
2025-06-30 10:33:40 +00:00
|
|
|
await get_tree().create_timer(duration).timeout
|
|
|
|
|
|
|
|
|
|
|
|
func timer(duration: float, callable: Callable) -> SceneTreeTimer:
|
|
|
|
var t = get_tree().create_timer(duration, false)
|
|
|
|
t.timeout.connect(callable)
|
|
|
|
return t
|
|
|
|
|
|
|
|
|
|
|
|
#### Canvas
|
|
|
|
func shake_layer(layer: CanvasLayer, duration: float, delta := 2.0, fps := 20.0) -> void:
|
|
|
|
var tween = layer.create_tween()
|
|
|
|
# shake layer's offset
|
|
|
|
var origin_offset = layer.offset
|
|
|
|
var count = int(duration * fps)
|
|
|
|
var delta_t = 1.0 / fps
|
|
|
|
for i in range(count):
|
|
|
|
var offset = Vector2(randf_range(-delta, delta), randf_range(-delta, delta))
|
|
|
|
tween.tween_property(layer, "offset", origin_offset + offset, delta_t)
|
|
|
|
# tween back to origin
|
|
|
|
tween.tween_property(layer, "offset", origin_offset, delta_t)
|
|
|
|
|
|
|
|
|
|
|
|
###### Dialogue
|
|
|
|
func concact_content_from_lines(lines := []):
|
|
|
|
if lines.is_empty():
|
|
|
|
return ""
|
|
|
|
var content = ""
|
|
|
|
for i in range(len(lines) - 1):
|
|
|
|
var line = lines[i] as DialogueLine
|
|
|
|
content += TranslationServer.tr(line.translation_key) + "\n"
|
|
|
|
# last line without "\n"
|
|
|
|
content += TranslationServer.tr(lines[-1].translation_key)
|
|
|
|
return content
|
|
|
|
|
|
|
|
|
|
|
|
func get_lines(res: DialogueResource, title: String) -> Array:
|
|
|
|
var lines = []
|
|
|
|
var current_line = await res.get_next_dialogue_line(title)
|
|
|
|
while current_line:
|
|
|
|
lines.append(current_line)
|
|
|
|
if current_line.next_id != "end":
|
|
|
|
current_line = await res.get_next_dialogue_line(current_line.next_id)
|
|
|
|
else:
|
|
|
|
break
|
|
|
|
return lines
|
|
|
|
|
|
|
|
|
|
|
|
# pop os lines
|
|
|
|
func generate_lines(content: String) -> Array:
|
|
|
|
var text = "~ title\n" + content + "\n=> END"
|
|
|
|
var res = DialogueManager.create_resource_from_text(text)
|
|
|
|
return await get_lines(res, "title")
|
2025-07-23 09:07:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
#### Geometry
|
|
|
|
|
|
|
|
|
|
|
|
# This function finds the closest point on the boundary or inside of a polygon
|
|
|
|
# to a given point.
|
|
|
|
#
|
|
|
|
# @param point: The Vector2 point to test against.
|
|
|
|
# @param polygon_vertices: A PackedVector2Array defining the polygon.
|
|
|
|
# @return: The Vector2 coordinate of the closest point.
|
|
|
|
func get_closest_point_on_polygon(point: Vector2, polygon_vertices: PackedVector2Array) -> Vector2:
|
|
|
|
var vertex_count = polygon_vertices.size()
|
|
|
|
if vertex_count == 0:
|
|
|
|
return Vector2.ZERO # Or handle error appropriately
|
|
|
|
if vertex_count == 1:
|
|
|
|
return polygon_vertices[0]
|
|
|
|
|
|
|
|
# First, check if the point is already inside the polygon.
|
|
|
|
# If so, the point itself is the answer.
|
|
|
|
if Geometry2D.is_point_in_polygon(point, polygon_vertices):
|
|
|
|
return point
|
|
|
|
|
|
|
|
# If the point is outside, we need to find the closest point on its edges.
|
|
|
|
var closest_point_so_far: Vector2
|
|
|
|
var min_dist_sq = INF # Use infinity as the initial maximum distance
|
|
|
|
|
|
|
|
# Iterate through each edge of the polygon.
|
|
|
|
for i in range(vertex_count):
|
|
|
|
# An edge is a segment between the current vertex and the next one.
|
|
|
|
# The modulo operator (%) handles the last edge connecting the last vertex to the first.
|
|
|
|
var p1 = polygon_vertices[i]
|
|
|
|
var p2 = polygon_vertices[(i + 1) % vertex_count]
|
|
|
|
|
|
|
|
# Get the closest point on the current line segment.
|
|
|
|
var closest_point_on_segment = Geometry2D.get_closest_point_to_segment(point, p1, p2)
|
|
|
|
|
|
|
|
# Calculate the squared distance. This is more efficient than using sqrt().
|
|
|
|
var dist_sq = point.distance_squared_to(closest_point_on_segment)
|
|
|
|
|
|
|
|
# If this point is closer than any we've seen before, update our variables.
|
|
|
|
if dist_sq < min_dist_sq:
|
|
|
|
min_dist_sq = dist_sq
|
|
|
|
closest_point_so_far = closest_point_on_segment
|
|
|
|
|
|
|
|
return closest_point_so_far
|