Clean and hard-typing

This commit is contained in:
Adrien Ufferte
2025-04-29 13:48:27 +02:00
parent c1b1a8d981
commit 0cfe83778c
58 changed files with 433 additions and 428 deletions
+3 -3
View File
@@ -9,14 +9,14 @@ func write_folder_recursive(abs_path: String, rel_path: String) -> Error:
var file_name: String = dir.get_next() var file_name: String = dir.get_next()
while file_name != "": while file_name != "":
if dir.current_is_dir(): if dir.current_is_dir():
var error: = write_folder_recursive(abs_path, rel_path.path_join(file_name)) var error: Error = write_folder_recursive(abs_path, rel_path.path_join(file_name))
if error != OK: if error != OK:
return error return error
else: else:
var error: = start_file(rel_path.path_join(file_name)) var error: Error = start_file(rel_path.path_join(file_name))
if error != OK: if error != OK:
return error return error
var file: = FileAccess.open(abs_path.path_join(rel_path).path_join(file_name), FileAccess.READ) var file: FileAccess = FileAccess.open(abs_path.path_join(rel_path).path_join(file_name), FileAccess.READ)
write_file(file.get_buffer(file.get_length())) write_file(file.get_buffer(file.get_length()))
file_name = dir.get_next() file_name = dir.get_next()
else: else:
+1 -1
View File
@@ -1,4 +1,4 @@
extends Resource extends Resource
class_name ProfToolSave class_name ProfToolSave
@export var selected_language: = "" @export var selected_language: String = ""
+8 -8
View File
@@ -25,8 +25,8 @@ class Flower:
class LessonButton: class LessonButton:
var position: = Vector2i.ZERO var position: Vector2i = Vector2i.ZERO
var path_out_position: = Vector2i.ZERO var path_out_position: Vector2i = Vector2i.ZERO
func _init(p_position: Vector2i = Vector2i.ZERO, p_path_out_position: Vector2i = Vector2i.ZERO) -> void: func _init(p_position: Vector2i = Vector2i.ZERO, p_path_out_position: Vector2i = Vector2i.ZERO) -> void:
position = p_position position = p_position
@@ -49,7 +49,7 @@ enum FirstOrLast {
} }
@export var color: = 0 @export var color: int = 0
var flowers: Array[Flower] = []: var flowers: Array[Flower] = []:
set = set_flowers set = set_flowers
@export var flowers_export: Array[Dictionary] = []: @export var flowers_export: Array[Dictionary] = []:
@@ -58,32 +58,32 @@ var lesson_buttons: Array[LessonButton] = []:
set = set_lesson_buttons set = set_lesson_buttons
@export var lesson_buttons_export: Array[Dictionary] = []: @export var lesson_buttons_export: Array[Dictionary] = []:
set = set_lesson_buttons_export set = set_lesson_buttons_export
@export var is_first_or_last: = FirstOrLast.Neither @export var is_first_or_last: FirstOrLast = FirstOrLast.Neither
func set_flowers_export(p_flowers_export: Array[Dictionary]) -> void: func set_flowers_export(p_flowers_export: Array[Dictionary]) -> void:
flowers_export = p_flowers_export flowers_export = p_flowers_export
flowers.clear() flowers.clear()
for flower_dict in flowers_export: for flower_dict: Dictionary in flowers_export:
flowers.append(Flower.from_dict(flower_dict)) flowers.append(Flower.from_dict(flower_dict))
func set_flowers(p_flowers: Array[Flower]) -> void: func set_flowers(p_flowers: Array[Flower]) -> void:
flowers = p_flowers flowers = p_flowers
flowers_export.clear() flowers_export.clear()
for flower in flowers: for flower: Flower in flowers:
flowers_export.append(flower.to_dict()) flowers_export.append(flower.to_dict())
func set_lesson_buttons_export(p_lesson_buttons_export: Array[Dictionary]) -> void: func set_lesson_buttons_export(p_lesson_buttons_export: Array[Dictionary]) -> void:
lesson_buttons_export = p_lesson_buttons_export lesson_buttons_export = p_lesson_buttons_export
lesson_buttons.clear() lesson_buttons.clear()
for lesson_button_dict in lesson_buttons_export: for lesson_button_dict: Dictionary in lesson_buttons_export:
lesson_buttons.append(LessonButton.from_dict(lesson_button_dict)) lesson_buttons.append(LessonButton.from_dict(lesson_button_dict))
func set_lesson_buttons(p_lesson_buttons: Array[LessonButton]) -> void: func set_lesson_buttons(p_lesson_buttons: Array[LessonButton]) -> void:
lesson_buttons = p_lesson_buttons lesson_buttons = p_lesson_buttons
lesson_buttons_export.clear() lesson_buttons_export.clear()
for lesson_button in lesson_buttons: for lesson_button: LessonButton in lesson_buttons:
lesson_buttons_export.append(lesson_button.to_dict()) lesson_buttons_export.append(lesson_button.to_dict())
+1 -1
View File
@@ -37,6 +37,6 @@ func update_scores(minigame_scores: Dictionary) -> void:
if new_score >= 0: if new_score >= 0:
gps_scores.erase(ID) gps_scores.erase(ID)
else: else:
gps_scores[ID] = max(min_score, new_score) gps_scores[ID] = maxi(min_score, new_score)
score_changed.emit() score_changed.emit()
+3 -3
View File
@@ -15,7 +15,7 @@ func play() -> void:
audio_stream_player.stream = sounds.pick_random() audio_stream_player.stream = sounds.pick_random()
audio_stream_player.play() audio_stream_player.play()
for p in particles: for particle: GPUParticles2D in particles:
p.amount = randi_range(10, 16) particle.amount = randi_range(10, 16)
p.restart() particle.restart()
await get_tree().create_timer(randf_range(0.1, 0.2)).timeout await get_tree().create_timer(randf_range(0.1, 0.2)).timeout
+50 -50
View File
@@ -7,20 +7,20 @@ const LessonButton: = preload("res://sources/lesson_screen/lesson_button.gd")
const MinigameLayout: = preload("res://sources/gardens/minigame_layout.gd") const MinigameLayout: = preload("res://sources/gardens/minigame_layout.gd")
const Kalulu: = preload("res://sources/minigames/base/kalulu.gd") const Kalulu: = preload("res://sources/minigames/base/kalulu.gd")
const garden_scene: = preload("res://resources/gardens/garden.tscn") const garden_scene: PackedScene = preload("res://resources/gardens/garden.tscn")
const look_and_learn_scene: = preload("res://sources/look_and_learn/look_and_learn.tscn") const look_and_learn_scene: PackedScene = preload("res://sources/look_and_learn/look_and_learn.tscn")
const flower_fvx: = preload("res://sources/gardens/flower_particle.tscn") const flower_fvx: PackedScene = preload("res://sources/gardens/flower_particle.tscn")
const garden_size: int = 2400 const garden_size: int = 2400
@export_category("Layout") @export_category("Layout")
@export var gardens_layout: GardensLayout: @export var gardens_layout: GardensLayout:
set = set_gardens_layout set = set_gardens_layout
@export var starting_garden: = -1 @export var starting_garden: int = -1
@export_category("Colors") @export_category("Colors")
@export var unlocked_color: = Color("1c2662") #blue @export var unlocked_color: Color = Color("1c2662") #blue
@export var locked_color: = Color("1d2229") #black @export var locked_color: Color = Color("1d2229") #black
@export_group("Minigames") @export_group("Minigames")
@export var minigames_scenes: Array[PackedScene] @export var minigames_scenes: Array[PackedScene]
@@ -50,21 +50,21 @@ const garden_size: int = 2400
@onready var kalulu: Kalulu = %Kalulu @onready var kalulu: Kalulu = %Kalulu
@onready var kalulu_button: CanvasItem = %KaluluButton @onready var kalulu_button: CanvasItem = %KaluluButton
@onready var intro_speech: = Database.load_external_sound(Database.get_kalulu_speech_path("gardens_screen", "intro")) @onready var intro_speech: AudioStreamMP3 = Database.load_external_sound(Database.get_kalulu_speech_path("gardens_screen", "intro"))
@onready var help_few_plants_speech: = Database.load_external_sound(Database.get_kalulu_speech_path("gardens_screen", "help_few_plants")) @onready var help_few_plants_speech: AudioStreamMP3 = Database.load_external_sound(Database.get_kalulu_speech_path("gardens_screen", "help_few_plants"))
@onready var help_many_plants_speech: = Database.load_external_sound(Database.get_kalulu_speech_path("gardens_screen", "help_many_plants")) @onready var help_many_plants_speech: AudioStreamMP3 = Database.load_external_sound(Database.get_kalulu_speech_path("gardens_screen", "help_many_plants"))
var lessons: = {} var lessons: Dictionary
var points: Array[Array]= [] var points: Array[Array]
var is_scrolling: = false var is_scrolling: bool = false
var scroll_beginning_garden: int = 0 var scroll_beginning_garden: int = 0
var scroll_tween: Tween var scroll_tween: Tween
var is_locked: = false var is_locked: bool = false
var in_minigame_selection: = false var in_minigame_selection: bool = false
var current_lesson_number: = -1 var current_lesson_number: int = -1
var current_garden: Garden var current_garden: Garden
var current_button_global_position: = Vector2.ZERO var current_button_global_position: Vector2 = Vector2.ZERO
var current_button: LessonButton var current_button: LessonButton
static var transition_data: Dictionary static var transition_data: Dictionary
@@ -77,11 +77,11 @@ func _ready() -> void:
INNER JOIN GPsInLessons ON GPsInLessons.LessonID = Lessons.ID INNER JOIN GPsInLessons ON GPsInLessons.LessonID = Lessons.ID
INNER JOIN GPs ON GPsInLessons.GPID = GPs.ID INNER JOIN GPs ON GPsInLessons.GPID = GPs.ID
ORDER BY LessonNb") ORDER BY LessonNb")
for e in Database.db.query_result: for element: Dictionary in Database.db.query_result:
if not lessons.has(e.LessonNb): if not lessons.has(element.LessonNb):
lessons[e.LessonNb] = [] lessons[element.LessonNb] = []
var lesson_array: Array = lessons[e.LessonNb] var lesson_array: Array = lessons[element.LessonNb]
lesson_array.append({grapheme = e.Grapheme, phoneme = e.Phoneme, gp_id = e.GPID}) lesson_array.append({grapheme = element.Grapheme, phoneme = element.Phoneme, gp_id = element.GPID})
# Loads the layout # Loads the layout
if not gardens_layout: if not gardens_layout:
@@ -104,7 +104,7 @@ func _ready() -> void:
# Transition variables # # Transition variables #
# The maximum unlocked lesson by the player # The maximum unlocked lesson by the player
var max_unlocked_lesson: = UserDataManager.student_progression.get_max_unlocked_lesson() + 1 var max_unlocked_lesson: int = UserDataManager.student_progression.get_max_unlocked_lesson() + 1
# Defines if the last played minigame or lookandlearn is of the last available lesson # Defines if the last played minigame or lookandlearn is of the last available lesson
var is_current_lesson: bool = transition_data and transition_data.current_lesson_number == max_unlocked_lesson var is_current_lesson: bool = transition_data and transition_data.current_lesson_number == max_unlocked_lesson
@@ -124,7 +124,7 @@ func _ready() -> void:
#region Progression #region Progression
# Loads the progression of the player without the newly unlocked stuff from the transition data # Loads the progression of the player without the newly unlocked stuff from the transition data
var lesson_ind: = 1 var lesson_ind: int = 1
# Go through each garden # Go through each garden
for garden_control: Garden in garden_parent.get_children(): for garden_control: Garden in garden_parent.get_children():
@@ -161,7 +161,7 @@ func _ready() -> void:
button.completed = UserDataManager.student_progression.is_lesson_completed(lesson_ind) button.completed = UserDataManager.student_progression.is_lesson_completed(lesson_ind)
# Handles progression of the minigames # Handles progression of the minigames
for k in range(3): for k: int in range(3):
garden_control.max_progression += 2.0 garden_control.max_progression += 2.0
match UserDataManager.student_progression.unlocks[lesson_ind]["games"][k]: match UserDataManager.student_progression.unlocks[lesson_ind]["games"][k]:
UserProgression.Status.Unlocked: UserProgression.Status.Unlocked:
@@ -177,7 +177,7 @@ func _ready() -> void:
# Handles the flowers # Handles the flowers
var total_flowers: float = garden_control.get_progress_ratio() * garden_control.flower_controls.size() * 3.0 var total_flowers: float = garden_control.get_progress_ratio() * garden_control.flower_controls.size() * 3.0
var flower_ind: = 0 var flower_ind: int = 0
while total_flowers > 0 and flower_ind < garden_control.flower_controls.size(): while total_flowers > 0 and flower_ind < garden_control.flower_controls.size():
if total_flowers >= 3.0: if total_flowers >= 3.0:
@@ -193,14 +193,14 @@ func _ready() -> void:
garden_control.update_flowers() garden_control.update_flowers()
# Handles the path # Handles the path
var c: = Curve2D.new() var curve: Curve2D = Curve2D.new()
var max_lesson: = UserDataManager.student_progression.get_max_unlocked_lesson() var max_lesson: int = UserDataManager.student_progression.get_max_unlocked_lesson()
if not new_lesson_unlocked: if not new_lesson_unlocked:
max_lesson += 1 max_lesson += 1
for index: int in range(max_lesson): for index: int in range(max_lesson):
c.add_point(points[index][0] as Vector2, points[index][1] as Vector2, points[index][2] as Vector2) curve.add_point(points[index][0] as Vector2, points[index][1] as Vector2, points[index][2] as Vector2)
unlocked_line.points = c.get_baked_points() unlocked_line.points = curve.get_baked_points()
line_particles.global_position = unlocked_line.points[unlocked_line.points.size()-1] line_particles.global_position = unlocked_line.points[unlocked_line.points.size()-1]
@@ -212,7 +212,7 @@ func _ready() -> void:
if not transition_data: if not transition_data:
if starting_garden == -1: if starting_garden == -1:
lesson_ind = 1 lesson_ind = 1
for garden_ind in garden_parent.get_child_count(): for garden_ind: int in garden_parent.get_child_count():
var garden_control: Garden = garden_parent.get_child(garden_ind) var garden_control: Garden = garden_parent.get_child(garden_ind)
if starting_garden != -1: if starting_garden != -1:
break break
@@ -267,11 +267,11 @@ func _ready() -> void:
# Calculate the progression of the garden # Calculate the progression of the garden
current_garden.current_progression += 1 current_garden.current_progression += 1
var unlocks_ratio: = current_garden.current_progression / current_garden.max_progression var unlocks_ratio: float = current_garden.current_progression / current_garden.max_progression
var total_flowers: float = unlocks_ratio * current_garden.flower_controls.size() * 3.0 var total_flowers: float = unlocks_ratio * current_garden.flower_controls.size() * 3.0
var flower_ind: = 0 var flower_ind: int = 0
while total_flowers > 0 and flower_ind < current_garden.flower_controls.size(): while total_flowers > 0 and flower_ind < current_garden.flower_controls.size():
var play_animation: = false var play_animation: bool = false
if total_flowers >= 3.0 and current_garden.flowers_sizes[flower_ind] != Garden.FlowerSizes.Large: if total_flowers >= 3.0 and current_garden.flowers_sizes[flower_ind] != Garden.FlowerSizes.Large:
current_garden.flowers_sizes[flower_ind] = Garden.FlowerSizes.Large current_garden.flowers_sizes[flower_ind] = Garden.FlowerSizes.Large
total_flowers -= 3.0 total_flowers -= 3.0
@@ -340,7 +340,7 @@ func _ready() -> void:
await last_lesson_button.right() await last_lesson_button.right()
# Fill in the path towards the next lesson # Fill in the path towards the next lesson
var animation_curve: = Curve2D.new() var animation_curve: Curve2D = Curve2D.new()
for index: int in range(max_lesson-1, max_lesson + 1): for index: int in range(max_lesson-1, max_lesson + 1):
animation_curve.add_point(points[index][0] as Vector2, points[index][1] as Vector2, points[index][2] as Vector2) animation_curve.add_point(points[index][0] as Vector2, points[index][1] as Vector2, points[index][2] as Vector2)
@@ -349,7 +349,7 @@ func _ready() -> void:
@warning_ignore("integer_division") @warning_ignore("integer_division")
scroll_beginning_garden = scroll_container.scroll_horizontal / garden_size scroll_beginning_garden = scroll_container.scroll_horizontal / garden_size
var target_scroll: int = scroll_beginning_garden * garden_size + garden_size var target_scroll: int = scroll_beginning_garden * garden_size + garden_size
var tween: = create_tween() var tween: Tween = create_tween()
tween.set_ease(Tween.EASE_IN_OUT) tween.set_ease(Tween.EASE_IN_OUT)
tween.tween_property(scroll_container, "scroll_horizontal", target_scroll, 4) tween.tween_property(scroll_container, "scroll_horizontal", target_scroll, 4)
@@ -359,7 +359,7 @@ func _ready() -> void:
current_garden = garden_parent.get_child(scroll_beginning_garden) current_garden = garden_parent.get_child(scroll_beginning_garden)
line_audio_stream_player.pitch_scale = 0.95 line_audio_stream_player.pitch_scale = 0.95
var baked_points: = animation_curve.get_baked_points() var baked_points: PackedVector2Array = animation_curve.get_baked_points()
for point: Vector2 in baked_points: for point: Vector2 in baked_points:
if not line_audio_stream_player.playing: if not line_audio_stream_player.playing:
line_audio_stream_player.pitch_scale += 0.05 line_audio_stream_player.pitch_scale += 0.05
@@ -405,7 +405,7 @@ func _open_minigames_layout(button: LessonButton, lesson_ind: int) -> void:
in_minigame_selection = true in_minigame_selection = true
# Gets the correct exercises for the lesson # Gets the correct exercises for the lesson
var exercises: = Database.get_exercice_for_lesson(lesson_ind) var exercises: Array[int] = Database.get_exercice_for_lesson(lesson_ind)
if not exercises or exercises.size() < 3: if not exercises or exercises.size() < 3:
return return
@@ -454,7 +454,7 @@ func _open_minigames_layout(button: LessonButton, lesson_ind: int) -> void:
minigame_background_center.global_position = current_button_global_position minigame_background_center.global_position = current_button_global_position
minigame_background_center.visible = true minigame_background_center.visible = true
var tween: = create_tween().set_parallel(true).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK) var tween: Tween = create_tween().set_parallel(true).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK)
tween.tween_property(minigame_background_center, "scale", (1800.0 / 300.0) * Vector2.ONE, 0.25) tween.tween_property(minigame_background_center, "scale", (1800.0 / 300.0) * Vector2.ONE, 0.25)
tween.tween_property(minigame_background_center, "global_position", Vector2(380.0, 0), 0.25) tween.tween_property(minigame_background_center, "global_position", Vector2(380.0, 0), 0.25)
tween.tween_property(minigame_background, "scale", (1800.0 / 300.0) * Vector2.ONE, 0.25) tween.tween_property(minigame_background, "scale", (1800.0 / 300.0) * Vector2.ONE, 0.25)
@@ -510,9 +510,9 @@ func _close_minigames_layout() -> void:
feedback_audio_stream_player2.pitch_scale = 0.75 feedback_audio_stream_player2.pitch_scale = 0.75
feedback_audio_stream_player2.play() feedback_audio_stream_player2.play()
var tween: = create_tween().set_parallel(true).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK) var tween: Tween = create_tween().set_parallel(true).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK)
tween.tween_property(minigame_selection, "modulate:a", 0.0, 0.25) tween.tween_property(minigame_selection, "modulate:a", 0.0, 0.25)
var other_tween: = tween.chain() var other_tween: Tween = tween.chain()
other_tween.tween_property(minigame_background_center, "scale", Vector2.ONE, 0.25) other_tween.tween_property(minigame_background_center, "scale", Vector2.ONE, 0.25)
other_tween.tween_property(minigame_background_center, "global_position", current_button_global_position, 0.25) other_tween.tween_property(minigame_background_center, "global_position", current_button_global_position, 0.25)
other_tween.tween_property(minigame_background, "scale", Vector2.ONE, 0.25) other_tween.tween_property(minigame_background, "scale", Vector2.ONE, 0.25)
@@ -538,9 +538,9 @@ func _close_minigames_layout() -> void:
func _set_up_lessons() -> void: func _set_up_lessons() -> void:
var lesson_ind: = 1 var lesson_ind: int = 1
for garden_ind in garden_parent.get_child_count(): for garden_ind: int in garden_parent.get_child_count():
var garden_control: Garden = garden_parent.get_child(garden_ind) var garden_control: Garden = garden_parent.get_child(garden_ind)
@@ -565,13 +565,13 @@ func add_gardens() -> void:
return return
# Removes old gardens # Removes old gardens
for child in garden_parent.get_children(): for child: Node in garden_parent.get_children():
child.free() child.free()
# Adds the gardens needed from the layout configuration # Adds the gardens needed from the layout configuration
var current_lesson_count: int = 0 var current_lesson_count: int = 0
var garden_index: int = 0 var garden_index: int = 0
for garden_layout in gardens_layout.gardens: for garden_layout: GardenLayout in gardens_layout.gardens:
var garden: Garden = garden_scene.instantiate() var garden: Garden = garden_scene.instantiate()
garden_parent.add_child(garden) garden_parent.add_child(garden)
garden.garden_index = garden_index garden.garden_index = garden_index
@@ -602,14 +602,14 @@ func set_up_path() -> void:
break break
var garden_layout: GardenLayout = gardens_layout.gardens[index] var garden_layout: GardenLayout = gardens_layout.gardens[index]
var garden_control: Garden = garden_parent.get_child(index) var garden_control: Garden = garden_parent.get_child(index)
for b in garden_layout.lesson_buttons: for button in garden_layout.lesson_buttons:
var point_position: Vector2 = garden_parent.position + garden_control.position + Vector2(b.position) var point_position: Vector2 = garden_parent.position + garden_control.position + Vector2(button.position)
point_position += garden_control.get_button_size() / 2 point_position += garden_control.get_button_size() / 2
var point_in_position: = Vector2.ZERO var point_in_position: Vector2 = Vector2.ZERO
if curve.point_count > 1: if curve.point_count > 1:
point_in_position = curve.get_point_position(curve.point_count - 1) + curve.get_point_out(curve.point_count - 1) - point_position point_in_position = curve.get_point_position(curve.point_count - 1) + curve.get_point_out(curve.point_count - 1) - point_position
curve.add_point(point_position, point_in_position, b.path_out_position) curve.add_point(point_position, point_in_position, button.path_out_position)
points.append([point_position, point_in_position, b.path_out_position]) points.append([point_position, point_in_position, button.path_out_position])
locked_line.points = curve.get_baked_points() locked_line.points = curve.get_baked_points()
@@ -684,7 +684,7 @@ func _on_scroll_container_gui_input(event: InputEvent) -> void:
is_scrolling = false is_scrolling = false
var shift_value: int = scroll_container.scroll_horizontal - scroll_beginning_garden * garden_size var shift_value: int = scroll_container.scroll_horizontal - scroll_beginning_garden * garden_size
var target_scroll: int = scroll_beginning_garden * garden_size var target_scroll: int = scroll_beginning_garden * garden_size
var is_garden_changed: = false var is_garden_changed: bool = false
if shift_value < - 400: if shift_value < - 400:
target_scroll -= garden_size target_scroll -= garden_size
is_garden_changed = true is_garden_changed = true
+42 -42
View File
@@ -7,7 +7,7 @@ const gardens_layout_resource_path: String = "res://resources/gardens/gardens_la
var dragging_element: Variant var dragging_element: Variant
var drag_data: = {} var drag_data: Dictionary = {}
func _ready() -> void: func _ready() -> void:
@@ -45,8 +45,8 @@ func _init_gardens_layout() -> void:
garden_layout.color = (index / 4) % garden_textures_nb garden_layout.color = (index / 4) % garden_textures_nb
# Add the flowers to the garden # Add the flowers to the garden
for flower_i in 5: for flower_i: int in 5:
var flower: = GardenLayout.Flower.new(garden_layout.color, flower_i, Vector2i(980 + flower_i * 100, 900)) var flower: GardenLayout.Flower = GardenLayout.Flower.new(garden_layout.color, flower_i, Vector2i(980 + flower_i * 100, 900))
garden_layout.flowers.append(flower) garden_layout.flowers.append(flower)
garden_layout.flowers = garden_layout.flowers garden_layout.flowers = garden_layout.flowers
else: else:
@@ -62,17 +62,17 @@ func _init_gardens_layout() -> void:
func set_up_click_detection() -> void: func set_up_click_detection() -> void:
for garden_control_ind in garden_parent.get_child_count(): for garden_control_ind: int in garden_parent.get_child_count():
var garden_control: Garden = garden_parent.get_child(garden_control_ind) var garden_control: Garden = garden_parent.get_child(garden_control_ind)
for flower_ind in garden_control.flower_controls.size(): for flower_ind: int in garden_control.flower_controls.size():
var flower_control: Control = garden_control.flower_controls[flower_ind] var flower_control: Control = garden_control.flower_controls[flower_ind]
flower_control.gui_input.connect(_on_flower_gui_input.bind(garden_control_ind, flower_ind, flower_control)) flower_control.gui_input.connect(_on_flower_gui_input.bind(garden_control_ind, flower_ind, flower_control))
garden_control.flowers_sizes[flower_ind] = Garden.FlowerSizes.Large garden_control.flowers_sizes[flower_ind] = Garden.FlowerSizes.Large
garden_control.update_flowers() garden_control.update_flowers()
for lesson_button_ind in garden_control.lesson_button_controls.size(): for lesson_button_ind: int in garden_control.lesson_button_controls.size():
var lesson_button_control: Control = garden_control.lesson_button_controls[lesson_button_ind] var lesson_button_control: Control = garden_control.lesson_button_controls[lesson_button_ind]
lesson_button_control.gui_input.connect(_on_lesson_button_gui_input.bind(garden_control_ind, lesson_button_ind, lesson_button_control)) lesson_button_control.gui_input.connect(_on_lesson_button_gui_input.bind(garden_control_ind, lesson_button_ind, lesson_button_control))
@@ -102,13 +102,13 @@ func _input(event: InputEvent) -> void:
return return
if event.is_action_released("left_click"): if event.is_action_released("left_click"):
if drag_data.type == "flower": if drag_data.type == "flower":
var dragging_control: = dragging_element as Control var dragging_control: Control = dragging_element as Control
dragging_element.z_index = 2 dragging_element.z_index = 2
gardens_layout.gardens[drag_data.garden_ind].flowers[drag_data.flower_ind].position = dragging_control.get_parent_control().get_local_mouse_position() gardens_layout.gardens[drag_data.garden_ind].flowers[drag_data.flower_ind].position = dragging_control.get_parent_control().get_local_mouse_position()
gardens_layout.gardens[drag_data.garden_ind].flowers = gardens_layout.gardens[drag_data.garden_ind].flowers gardens_layout.gardens[drag_data.garden_ind].flowers = gardens_layout.gardens[drag_data.garden_ind].flowers
ResourceSaver.save(gardens_layout, gardens_layout.resource_path) ResourceSaver.save(gardens_layout, gardens_layout.resource_path)
elif drag_data.type == "lesson_button": elif drag_data.type == "lesson_button":
var dragging_control: = dragging_element as Control var dragging_control: Control = dragging_element as Control
dragging_element.z_index = 1 dragging_element.z_index = 1
gardens_layout.gardens[drag_data.garden_ind].lesson_buttons[drag_data.lesson_button_ind].position = _correct_position(dragging_control, dragging_control.get_parent_control().get_local_mouse_position()) gardens_layout.gardens[drag_data.garden_ind].lesson_buttons[drag_data.lesson_button_ind].position = _correct_position(dragging_control, dragging_control.get_parent_control().get_local_mouse_position())
gardens_layout.gardens[drag_data.garden_ind].lesson_buttons = gardens_layout.gardens[drag_data.garden_ind].lesson_buttons gardens_layout.gardens[drag_data.garden_ind].lesson_buttons = gardens_layout.gardens[drag_data.garden_ind].lesson_buttons
@@ -119,36 +119,36 @@ func _input(event: InputEvent) -> void:
dragging_element = null dragging_element = null
func _unhandled_input(event: InputEvent) -> void: #func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("left_click"): #if event.is_action_pressed("left_click"):
# Get the closest point to the mouse ## Get the closest point to the mouse
var closest_point: = curve.get_closest_point(locked_line.get_local_mouse_position()) #var closest_point: = curve.get_closest_point(locked_line.get_local_mouse_position())
#
# If the user clicked on a line, do the drag event ## If the user clicked on a line, do the drag event
if closest_point.distance_to(locked_line.get_local_mouse_position()) < locked_line.width: #if closest_point.distance_to(locked_line.get_local_mouse_position()) < locked_line.width:
dragging_element = get_previous_point_on_curve(closest_point) #dragging_element = get_previous_point_on_curve(closest_point)
var a: = get_garden_and_sub_ind_from_ind(dragging_element as int) #var a: = get_garden_and_sub_ind_from_ind(dragging_element as int)
drag_data = { #drag_data = {
type = "path_middle", #type = "path_middle",
garden_ind = a[0], #garden_ind = a[0],
sub_ind = a[1], #sub_ind = a[1],
} #}
func get_previous_point_on_curve(point: Vector2) -> int: #func get_previous_point_on_curve(point: Vector2) -> int:
var offset: = curve.get_closest_offset(point) #var offset: = curve.get_closest_offset(point)
for index: int in curve.point_count: #for index: int in curve.point_count:
var point_offset: = curve.get_closest_offset(curve.get_point_position(index)) #var point_offset: = curve.get_closest_offset(curve.get_point_position(index))
if point_offset > offset: #if point_offset > offset:
return index - 1 #return index - 1
return curve.point_count #return curve.point_count
func get_garden_and_sub_ind_from_ind(ind: int) -> Array[int]: func get_garden_and_sub_ind_from_ind(ind: int) -> Array[int]:
var count: = 0 var count: int = 0
for garden_control_ind in garden_parent.get_child_count(): for garden_control_ind: int in garden_parent.get_child_count():
var garden_control: Garden = garden_parent.get_child(garden_control_ind) var garden_control: Garden = garden_parent.get_child(garden_control_ind)
for lesson_button_ind in garden_control.lesson_button_controls.size(): for lesson_button_ind: int in garden_control.lesson_button_controls.size():
if count == ind: if count == ind:
return [garden_control_ind, lesson_button_ind] return [garden_control_ind, lesson_button_ind]
count += 1 count += 1
@@ -156,7 +156,7 @@ func get_garden_and_sub_ind_from_ind(ind: int) -> Array[int]:
func get_best_showing_garden() -> int: func get_best_showing_garden() -> int:
for garden_ind in garden_parent.get_child_count(): for garden_ind: int in garden_parent.get_child_count():
var garden_control: Control = garden_parent.get_child(garden_ind) var garden_control: Control = garden_parent.get_child(garden_ind)
if abs(garden_control.global_position.x) < garden_control.size.x / 2: if abs(garden_control.global_position.x) < garden_control.size.x / 2:
return garden_ind return garden_ind
@@ -179,7 +179,7 @@ func _on_flower_gui_input(event: InputEvent, garden_control_ind: int, flower_ind
get_viewport().set_input_as_handled() get_viewport().set_input_as_handled()
elif event.is_action_pressed("right_click"): elif event.is_action_pressed("right_click"):
var garden: Garden = garden_parent.get_child(garden_control_ind) var garden: Garden = garden_parent.get_child(garden_control_ind)
var flower: = gardens_layout.gardens[garden_control_ind].flowers[flower_ind] var flower: GardenLayout.Flower = gardens_layout.gardens[garden_control_ind].flowers[flower_ind]
flower.type += 1 flower.type += 1
if flower.type >= flower_types_nb: if flower.type >= flower_types_nb:
flower.type = 0 flower.type = 0
@@ -200,10 +200,10 @@ func _on_lesson_button_gui_input(event: InputEvent, garden_control_ind: int, les
func _on_change_flower_color_button_pressed() -> void: func _on_change_flower_color_button_pressed() -> void:
var garden_ind: = get_best_showing_garden() var garden_ind: int = get_best_showing_garden()
var garden: Garden = garden_parent.get_child(garden_ind) var garden: Garden = garden_parent.get_child(garden_ind)
var flowers: = gardens_layout.gardens[garden_ind].flowers var flowers: Array[GardenLayout.Flower] = gardens_layout.gardens[garden_ind].flowers
for flower in flowers: for flower: GardenLayout.Flower in flowers:
flower.color += 1 flower.color += 1
if flower.color >= garden_textures_nb: if flower.color >= garden_textures_nb:
flower.color = 0 flower.color = 0
@@ -215,11 +215,11 @@ func _on_change_flower_color_button_pressed() -> void:
func _on_change_flower_color_button_2_pressed() -> void: func _on_change_flower_color_button_2_pressed() -> void:
var garden_ind: = get_best_showing_garden() var garden_ind: int = get_best_showing_garden()
var garden: Garden = garden_parent.get_child(garden_ind) var garden: Garden = garden_parent.get_child(garden_ind)
var flowers: = gardens_layout.gardens[garden_ind].flowers var flowers: Array[GardenLayout.Flower] = gardens_layout.gardens[garden_ind].flowers
for flower in flowers: for flower: GardenLayout.Flower in flowers:
flower.color -= 1 flower.color -= 1
if flower.color < 0: if flower.color < 0:
flower.color = garden_textures_nb - 1 flower.color = garden_textures_nb - 1
@@ -231,10 +231,10 @@ func _on_change_flower_color_button_2_pressed() -> void:
func _on_reset_garden_button_pressed() -> void: func _on_reset_garden_button_pressed() -> void:
var garden_ind: = get_best_showing_garden() var garden_ind: int = get_best_showing_garden()
var garden: Garden = garden_parent.get_child(garden_ind) var garden: Garden = garden_parent.get_child(garden_ind)
var flowers: = gardens_layout.gardens[garden_ind].flowers var flowers: Array[GardenLayout.Flower] = gardens_layout.gardens[garden_ind].flowers
for index: int in flowers.size(): for index: int in flowers.size():
flowers[index] = GardenLayout.Flower.new() flowers[index] = GardenLayout.Flower.new()
gardens_layout.gardens[garden_ind].flowers = flowers gardens_layout.gardens[garden_ind].flowers = flowers
+16 -16
View File
@@ -1,27 +1,27 @@
extends Control extends Control
var element_scene: = preload("res://sources/language_tool/gp_list_element.tscn") var element_scene: PackedScene = preload("res://sources/language_tool/gp_list_element.tscn")
@onready var elements_container: VBoxContainer = %ElementsContainer @onready var elements_container: VBoxContainer = %ElementsContainer
@onready var error_label: Label = %ErrorLabel @onready var error_label: Label = %ErrorLabel
var undo_redo: = UndoRedo.new() var undo_redo: UndoRedo = UndoRedo.new()
func _ready() -> void: func _ready() -> void:
var query: = "Select * FROM GPs ORDER BY GPs.Grapheme" var query: String = "Select * FROM GPs ORDER BY GPs.Grapheme"
Database.db.query(query) Database.db.query(query)
var result: = Database.db.query_result var result: Array[Dictionary] = Database.db.query_result
for e in result: for element_dico: Dictionary in result:
var element: GPListElement = element_scene.instantiate() var new_element: GPListElement = element_scene.instantiate()
element.grapheme = e.Grapheme new_element.grapheme = element_dico.Grapheme
element.phoneme = e.Phoneme new_element.phoneme = element_dico.Phoneme
element.type = e.Type new_element.type = element_dico.Type
element.exception = e.Exception new_element.exception = element_dico.Exception
element.undo_redo = undo_redo new_element.undo_redo = undo_redo
element.id = e.ID new_element.id = element_dico.ID
elements_container.add_child(element) elements_container.add_child(new_element)
element.delete_pressed.connect(_on_element_delete_pressed.bind(element)) new_element.delete_pressed.connect(_on_element_delete_pressed.bind(new_element))
for pseudo_button: Label in [%Grapheme, %Phoneme, %Type]: for pseudo_button: Label in [%Grapheme, %Phoneme, %Type]:
pseudo_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND pseudo_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
@@ -53,9 +53,9 @@ func _on_plus_button_pressed() -> void:
func _on_save_button_pressed() -> void: func _on_save_button_pressed() -> void:
for element: GPListElement in elements_container.get_children(): for element: GPListElement in elements_container.get_children():
element.insert_in_database() element.insert_in_database()
var query: = "Select * FROM GPs" var query: String = "Select * FROM GPs"
Database.db.query(query) Database.db.query(query)
var result: = Database.db.query_result var result: Array[Dictionary] = Database.db.query_result
for e in result: for e in result:
var found: = false var found: = false
for element: GPListElement in elements_container.get_children(): for element: GPListElement in elements_container.get_children():
+1 -1
View File
@@ -14,7 +14,7 @@ func _on_item_selected(index: int) -> void:
if index == 0: if index == 0:
new_selected.emit() new_selected.emit()
return return
var id: = get_item_id(index) var id: int = get_item_id(index)
gp_selected.emit(id) gp_selected.emit(id)
+7 -7
View File
@@ -22,13 +22,13 @@ enum Type {
var grapheme: = "": var grapheme: String = "":
set = set_grapheme set = set_grapheme
var phoneme: = "": var phoneme: String = "":
set = set_phoneme set = set_phoneme
var type: = Type.Silent: var type: GPListElement.Type = Type.Silent:
set = set_type set = set_type
var exception: = 0: var exception: bool = false:
set = set_exception set = set_exception
var id: int = -1 var id: int = -1
var undo_redo: UndoRedo: var undo_redo: UndoRedo:
@@ -107,9 +107,9 @@ func insert_in_database() -> void:
if id >= 0: if id >= 0:
Database.db.query_with_bindings("SELECT * FROM GPs WHERE ID=?", [id]) Database.db.query_with_bindings("SELECT * FROM GPs WHERE ID=?", [id])
if not Database.db.query_result.is_empty(): if not Database.db.query_result.is_empty():
var e = Database.db.query_result[0] var element: Dictionary = Database.db.query_result[0]
if grapheme != e.Grapheme or phoneme != e.Phoneme or type != e.Type or exception != e.Exception: if grapheme != element.Grapheme or phoneme != element.Phoneme or type != element.Type or exception != element.Exception:
Logger.trace("GPListElement: UPDATING %s" % e.Grapheme) Logger.trace("GPListElement: UPDATING %s" % element.Grapheme)
Database.db.update_rows("GPs", "ID=%s" % id, {Grapheme=grapheme, Phoneme=phoneme, Type=type, Exception=exception}) Database.db.update_rows("GPs", "ID=%s" % id, {Grapheme=grapheme, Phoneme=phoneme, Type=type, Exception=exception})
return return
@@ -1,4 +1,5 @@
extends MarginContainer extends MarginContainer
class_name LessonContainer
var gp_label_scene: = preload("res://sources/language_tool/lesson_gp_label.tscn") var gp_label_scene: = preload("res://sources/language_tool/lesson_gp_label.tscn")
+5 -4
View File
@@ -1,13 +1,14 @@
extends Label extends Label
class_name LessonGPLabel
signal gp_dropped(before: bool, data: Dictionary) signal gp_dropped(before: bool, data: Dictionary)
var gp_id: = -1 var gp_id: int = -1
var grapheme: = "": var grapheme: String = "":
set = set_grapheme set = set_grapheme
var phoneme: = "": var phoneme: String = "":
set = set_phoneme set = set_phoneme
var is_being_dragged: = false var is_being_dragged: bool = false
func set_grapheme(p_grapheme: String) -> void: func set_grapheme(p_grapheme: String) -> void:
+22 -22
View File
@@ -1,12 +1,12 @@
extends Control extends Control
@onready var lessons_container: = $%LessonsContainer @onready var lessons_container: MarginContainer = $%LessonsContainer
@onready var unused_gp_container: = $%UnusedGPContainer @onready var unused_gp_container: GridContainer = $%UnusedGPContainer
var lesson_container_scene: = preload("res://sources/language_tool/lesson_container.tscn") var lesson_container_scene: PackedScene = preload("res://sources/language_tool/lesson_container.tscn")
var gp_label_scene: = preload("res://sources/language_tool/lesson_gp_label.tscn") var gp_label_scene: PackedScene = preload("res://sources/language_tool/lesson_gp_label.tscn")
var lessons: = {} var lessons: Dictionary = {}
func _ready() -> void: func _ready() -> void:
@@ -14,35 +14,35 @@ func _ready() -> void:
INNER JOIN GPsInLessons ON GPsInLessons.LessonID = Lessons.ID INNER JOIN GPsInLessons ON GPsInLessons.LessonID = Lessons.ID
INNER JOIN GPs ON GPsInLessons.GPID = GPs.ID INNER JOIN GPs ON GPsInLessons.GPID = GPs.ID
ORDER BY LessonNb") ORDER BY LessonNb")
for e in Database.db.query_result: for element: Dictionary in Database.db.query_result:
if lessons.has(e.LessonNb): if lessons.has(element.LessonNb):
lessons[e.LessonNb].add_gp({grapheme = e.Grapheme, phoneme = e.Phoneme, gp_id = e.GPID}) (lessons[element.LessonNb] as LessonContainer).add_gp({grapheme = element.Grapheme, phoneme = element.Phoneme, gp_id = element.GPID})
else: else:
var lesson_container: = lesson_container_scene.instantiate() var lesson_container: LessonContainer = lesson_container_scene.instantiate()
lessons_container.add_child(lesson_container) lessons_container.add_child(lesson_container)
lesson_container.add_gp({grapheme = e.Grapheme, phoneme = e.Phoneme, gp_id = e.GPID}) lesson_container.add_gp({grapheme = element.Grapheme, phoneme = element.Phoneme, gp_id = element.GPID})
lesson_container.number = e.LessonNb lesson_container.number = element.LessonNb
lesson_container.lesson_dropped.connect(_on_lesson_dropped) lesson_container.lesson_dropped.connect(_on_lesson_dropped)
lessons[e.LessonNb] = lesson_container lessons[element.LessonNb] = lesson_container
Database.db.query("SELECT Grapheme, Phoneme, GPs.ID as GPID FROM GPs Database.db.query("SELECT Grapheme, Phoneme, GPs.ID as GPID FROM GPs
WHERE NOT EXISTS(SELECT 1 FROM GPsInLessons WHERE GPs.ID=GPsInLessons.GPID)") WHERE NOT EXISTS(SELECT 1 FROM GPsInLessons WHERE GPs.ID=GPsInLessons.GPID)")
for e in Database.db.query_result: for element: Dictionary in Database.db.query_result:
var gp_label: = gp_label_scene.instantiate() var gp_label: LessonGPLabel = gp_label_scene.instantiate()
unused_gp_container.add_child(gp_label) unused_gp_container.add_child(gp_label)
gp_label.grapheme = e.Grapheme gp_label.grapheme = element.Grapheme
gp_label.phoneme = e.Phoneme gp_label.phoneme = element.Phoneme
gp_label.gp_id = e.GPID gp_label.gp_id = element.GPID
gp_label.gp_dropped.connect(_on_gp_dropped) gp_label.gp_dropped.connect(_on_gp_dropped)
unused_gp_container.set_drag_forwarding(Callable(), _can_drop_in_gp_container, _drop_data_in_gp_container) unused_gp_container.set_drag_forwarding(Callable(), _can_drop_in_gp_container, _drop_data_in_gp_container)
func _on_plus_button_pressed() -> void: func _on_plus_button_pressed() -> void:
var lesson_container: = lesson_container_scene.instantiate() var lesson_container: LessonContainer = lesson_container_scene.instantiate()
lessons_container.add_child(lesson_container) lessons_container.add_child(lesson_container)
lesson_container.lesson_dropped.connect(_on_lesson_dropped) lesson_container.lesson_dropped.connect(_on_lesson_dropped)
var max_nb: = -1 var max_nb: int = -1
for e in lessons.values(): for e in lessons.values():
max_nb = max(max_nb, e.number) max_nb = max(max_nb, e.number)
lesson_container.number = max_nb + 1 lesson_container.number = max_nb + 1
@@ -56,7 +56,7 @@ func _can_drop_in_gp_container(_at_position: Vector2, data: Variant) -> bool:
func _drop_data_in_gp_container(_at_position: Vector2, data: Variant) -> void: func _drop_data_in_gp_container(_at_position: Vector2, data: Variant) -> void:
if not data.has("gp_id"): if not data.has("gp_id"):
return return
var new_gp_label: = gp_label_scene.instantiate() var new_gp_label: LessonGPLabel = gp_label_scene.instantiate()
new_gp_label.grapheme = data.grapheme new_gp_label.grapheme = data.grapheme
new_gp_label.phoneme = data.phoneme new_gp_label.phoneme = data.phoneme
new_gp_label.gp_id = data.gp_id new_gp_label.gp_id = data.gp_id
@@ -84,8 +84,8 @@ func _on_lesson_dropped(before: bool, number: int, dropped_number: int) -> void:
func _on_save_button_pressed() -> void: func _on_save_button_pressed() -> void:
Database.db.query("DELETE FROM GPsInLessons") Database.db.query("DELETE FROM GPsInLessons")
var children: = lessons_container.get_children() var children: Array[Node] = lessons_container.get_children()
for index in children.size(): for index: int in children.size():
var child: = children[index] var child: = children[index]
Database.db.query_with_bindings("SELECT * FROM Lessons WHERE LessonNb = ?", [index + 1]) Database.db.query_with_bindings("SELECT * FROM Lessons WHERE LessonNb = ?", [index + 1])
var lesson_id: = -1 var lesson_id: = -1
+5 -5
View File
@@ -43,11 +43,11 @@ func _on_button_pressed() -> void:
file_dialog.ok_button_text = "Add new elements" file_dialog.ok_button_text = "Add new elements"
for connection in file_dialog.file_selected.get_connections(): for connection: Dictionary in file_dialog.file_selected.get_connections():
connection["signal"].disconnect(connection["callable"]) (connection["signal"] as Signal).disconnect(connection["callable"] as Callable)
for connection in file_dialog.custom_action.get_connections(): for connection: Dictionary in file_dialog.custom_action.get_connections():
connection["signal"].disconnect(connection["callable"]) (connection["signal"] as Signal).disconnect(connection["callable"] as Callable)
file_dialog.file_selected.connect(_on_filename_selected) file_dialog.file_selected.connect(_on_filename_selected)
file_dialog.custom_action.connect(_on_match_to_file_selected) file_dialog.custom_action.connect(_on_match_to_file_selected)
@@ -59,7 +59,7 @@ func _on_filename_selected(path: String) -> void:
import_path_selected.emit(path, false) import_path_selected.emit(path, false)
func _on_match_to_file_selected(custom_action: String) -> void: func _on_match_to_file_selected(_custom_action: String) -> void:
import_path_selected.emit(file_dialog.current_path, true) import_path_selected.emit(file_dialog.current_path, true)
file_dialog.hide() file_dialog.hide()
+5 -5
View File
@@ -418,7 +418,7 @@ func _create_words_csv() -> void:
if gp_id_lesson < 0: if gp_id_lesson < 0:
lesson = -1 lesson = -1
break break
lesson = max(lesson, gp_id_lesson) lesson = maxi(lesson, gp_id_lesson)
gp_list_file.store_csv_line([element.Word, gpmatch, lesson, element.Reading, element.Writing]) gp_list_file.store_csv_line([element.Word, gpmatch, lesson, element.Reading, element.Writing])
@@ -447,7 +447,7 @@ func _create_syllable_csv() -> void:
if gp_id_lesson < 0: if gp_id_lesson < 0:
lesson = -1 lesson = -1
break break
lesson = max(lesson, gp_id_lesson) lesson = maxi(lesson, gp_id_lesson)
gp_list_file.store_csv_line([element.Syllable, gpmatch, lesson, element.Reading, element.Writing]) gp_list_file.store_csv_line([element.Syllable, gpmatch, lesson, element.Reading, element.Writing])
@@ -465,11 +465,11 @@ func _create_sentence_csv() -> void:
var lesson: int = -1 var lesson: int = -1
@warning_ignore("unsafe_method_access") @warning_ignore("unsafe_method_access")
for word_id: String in element.WordIDs.split(' '): for word_id: String in element.WordIDs.split(' '):
var i: int = Database.get_min_lesson_for_word_id(int(word_id)) var ind: int = Database.get_min_lesson_for_word_id(int(word_id))
if i < 0: if ind < 0:
lesson = -1 lesson = -1
break break
lesson = max(lesson, i) lesson = maxi(lesson, ind)
gp_list_file.store_csv_line([element.Sentence, lesson]) gp_list_file.store_csv_line([element.Sentence, lesson])
+16 -16
View File
@@ -11,8 +11,8 @@ signal changed()
@onready var segments_container: VBoxContainer = %SegmentsContainer @onready var segments_container: VBoxContainer = %SegmentsContainer
@onready var lines: Node2D = %Lines @onready var lines: Node2D = %Lines
const segment_build_class: = preload("res://sources/language_tool/segment_build.tscn") const segment_build_class: PackedScene = preload("res://sources/language_tool/segment_build.tscn")
const point_button_class: = preload("res://sources/language_tool/segment_point_button.tscn") const point_button_class: PackedScene = preload("res://sources/language_tool/segment_point_button.tscn")
var gradient: Gradient var gradient: Gradient
@@ -22,9 +22,9 @@ var buttons: Array[SegmentPointButton]
func reset() -> void: func reset() -> void:
var to_free: = lines.get_children() var to_free: Array[Node] = lines.get_children()
to_free.append_array(segments_container.get_children()) to_free.append_array(segments_container.get_children())
for node in to_free: for node: Node in to_free:
node.queue_free() node.queue_free()
current_segment = null current_segment = null
@@ -49,7 +49,7 @@ func _process(_delta: float) -> void:
current_button = null current_button = null
if is_instance_valid(current_button): if is_instance_valid(current_button):
var ind: = current_segment.remove_point(current_button.global_position - lines.global_position) var ind: int = current_segment.remove_point(current_button.global_position - lines.global_position)
current_button.global_position = get_global_mouse_position() current_button.global_position = get_global_mouse_position()
current_segment.add_point_at(current_button.global_position - lines.global_position, ind) current_segment.add_point_at(current_button.global_position - lines.global_position, ind)
@@ -58,14 +58,14 @@ func draw_segment(segment: SegmentBuild) -> void:
if not is_instance_valid(segment): if not is_instance_valid(segment):
return return
var ind_seg: = segments_container.get_children().find(segment) var ind_seg: int = segments_container.get_children().find(segment)
var line: Line2D = lines.get_child(ind_seg) var line: Line2D = lines.get_child(ind_seg)
line.points = Bezier.bezier_sampling(segment.points, max(points_per_lines, segment.points.size())) line.points = Bezier.bezier_sampling(segment.points, maxi(points_per_lines, segment.points.size()))
func draw_all_segments() -> void: func draw_all_segments() -> void:
for segment in segments_container.get_children(): for segment: SegmentBuild in segments_container.get_children():
draw_segment(segment) draw_segment(segment)
@@ -121,7 +121,7 @@ func _on_place_point_button_pressed() -> void:
func _on_add_segment_button_pressed() -> void: func _on_add_segment_button_pressed() -> void:
var segment_build: = segment_build_class.instantiate() var segment_build: SegmentBuild = segment_build_class.instantiate()
segments_container.add_child(segment_build) segments_container.add_child(segment_build)
segment_build.modify.connect(_on_segment_modify.bind(segment_build)) segment_build.modify.connect(_on_segment_modify.bind(segment_build))
@@ -129,16 +129,16 @@ func _on_add_segment_button_pressed() -> void:
current_segment = segment_build current_segment = segment_build
var line: = Line2D.new() var line: Line2D = Line2D.new()
line.width = 25 line.width = 25
line.begin_cap_mode = Line2D.LINE_CAP_ROUND line.begin_cap_mode = Line2D.LINE_CAP_ROUND
line.end_cap_mode = Line2D.LINE_CAP_ROUND line.end_cap_mode = Line2D.LINE_CAP_ROUND
line.joint_mode = Line2D.LINE_JOINT_ROUND line.joint_mode = Line2D.LINE_JOINT_ROUND
lines.add_child(line) lines.add_child(line)
var i: = segments_container.get_child_count() var i: int = segments_container.get_child_count()
var r: = float(i % points_per_gradient) / float(points_per_gradient) var r: float = float(i % points_per_gradient) / float(points_per_gradient)
var color: = gradient.sample(r) var color: Color = gradient.sample(r)
segment_build.set_color(color) segment_build.set_color(color)
line.default_color = color line.default_color = color
@@ -157,15 +157,15 @@ func _on_segment_modify(segment: SegmentBuild) -> void:
func _on_segment_delete(segment: SegmentBuild) -> void: func _on_segment_delete(segment: SegmentBuild) -> void:
if segment == current_segment: if segment == current_segment:
var possible_segments: = segments_container.get_children() var possible_segments: Array[Node] = segments_container.get_children()
if not possible_segments.is_empty(): if not possible_segments.is_empty():
current_segment = possible_segments[0] current_segment = possible_segments[0] as SegmentBuild
else: else:
current_segment = null current_segment = null
match_segment_with_buttons() match_segment_with_buttons()
var ind_seg: = segments_container.get_children().find(segment) var ind_seg: int = segments_container.get_children().find(segment)
lines.get_child(ind_seg).queue_free() lines.get_child(ind_seg).queue_free()
changed.emit() changed.emit()
@@ -13,13 +13,13 @@ func _ready() -> void:
func update_lesson() -> void: func update_lesson() -> void:
var m: = -1 var m: int = -1
for gp_id in gp_ids: for gp_id in gp_ids:
var i: = Database.get_min_lesson_for_word_id(gp_id) var i: int = Database.get_min_lesson_for_word_id(gp_id)
if i < 0: if i < 0:
m = -1 m = -1
break break
m = max(m, i) m = maxi(m, i)
lesson = m lesson = m
+39 -38
View File
@@ -6,8 +6,8 @@ signal new_GP_asked(i: int)
signal validated() signal validated()
signal GPs_updated() signal GPs_updated()
const gp_list_button_scene: = preload("res://sources/language_tool/gp_list_button.tscn") const gp_list_button_scene: PackedScene = preload("res://sources/language_tool/gp_list_button.tscn")
const plus_button_scene: = preload("res://sources/language_tool/plus_button.tscn") const plus_button_scene: PackedScene = preload("res://sources/language_tool/plus_button.tscn")
@export var table: String = "Words" @export var table: String = "Words"
@export var table_graph_column: String = "Word" @export var table_graph_column: String = "Word"
@@ -32,24 +32,24 @@ const plus_button_scene: = preload("res://sources/language_tool/plus_button.tscn
@onready var add_gp_button: MarginContainer = %AddGPButton @onready var add_gp_button: MarginContainer = %AddGPButton
@onready var remove_gp_button: MarginContainer = %RemoveGPButton2 @onready var remove_gp_button: MarginContainer = %RemoveGPButton2
var word: = "": var word: String = "":
set = set_word set = set_word
var lesson: = 0: var lesson: int = 0:
set = set_lesson set = set_lesson
var undo_redo: UndoRedo: var undo_redo: UndoRedo:
get: get:
if not undo_redo: if not undo_redo:
undo_redo = UndoRedo.new() undo_redo = UndoRedo.new()
return undo_redo return undo_redo
var id: = -1 var id: int = -1
var gp_ids: Array[int] = []: var gp_ids: Array[int] = []:
set = set_gp_ids set = set_gp_ids
var unvalidated_gp_ids: Array[int] = [] var unvalidated_gp_ids: Array[int] = []
var exception: = 0: var exception: int = 0:
set = set_exception set = set_exception
var reading: = 0: var reading: int = 0:
set = set_reading set = set_reading
var writing: = 0: var writing: int = 0:
set = set_writing set = set_writing
var sub_elements_list: Dictionary var sub_elements_list: Dictionary
@@ -92,11 +92,11 @@ func set_gp_ids(p_gp_ids: Array[int]) -> void:
func set_graphemes_edit(p_gp_ids: Array[int]) -> void: func set_graphemes_edit(p_gp_ids: Array[int]) -> void:
if graphemes_edit_container: if graphemes_edit_container:
for child in graphemes_edit_container.get_children(): for child: Node in graphemes_edit_container.get_children():
graphemes_edit_container.remove_child(child) graphemes_edit_container.remove_child(child)
child.queue_free() child.queue_free()
for ind_gp_id in p_gp_ids.size(): for ind_gp_id: int in p_gp_ids.size():
var gp_id: = p_gp_ids[ind_gp_id] var gp_id: int = p_gp_ids[ind_gp_id]
add_gp_list_button(gp_id, ind_gp_id) add_gp_list_button(gp_id, ind_gp_id)
@@ -117,27 +117,27 @@ func add_gp_list_button(gp_id: int, ind_gp_id: int) -> void:
func _on_gp_list_button_selected(gp_id: int, element: Node) -> void: func _on_gp_list_button_selected(gp_id: int, element: Node) -> void:
@warning_ignore("integer_division") @warning_ignore("integer_division")
var ind_gp_id: = element.get_index() / 2 var ind_gp_id: int = element.get_index() / 2
unvalidated_gp_ids[ind_gp_id] = gp_id unvalidated_gp_ids[ind_gp_id] = gp_id
word_edit.text = get_graphemes(unvalidated_gp_ids) word_edit.text = get_graphemes(unvalidated_gp_ids)
func _on_gp_list_button_new_selected(element: Node) -> void: func _on_gp_list_button_new_selected(element: Node) -> void:
@warning_ignore("integer_division") @warning_ignore("integer_division")
var ind_gp_id: = element.get_index() / 2 var ind_gp_id: int = element.get_index() / 2
new_GP_asked.emit(ind_gp_id) new_GP_asked.emit(ind_gp_id)
func get_graphemes(p_gp_ids: Array[int]) -> String: func get_graphemes(p_gp_ids: Array[int]) -> String:
var res: = "" var res: String = ""
for gp_id in p_gp_ids: for gp_id: int in p_gp_ids:
res += sub_elements_list[gp_id].grapheme res += sub_elements_list[gp_id].grapheme
return res return res
func get_gps(p_gp_ids: Array[int]) -> String: func get_gps(p_gp_ids: Array[int]) -> String:
var res: = "" var res: String = ""
for gp_id in p_gp_ids: for gp_id: int in p_gp_ids:
res += sub_elements_list[gp_id].grapheme res += sub_elements_list[gp_id].grapheme
res += "-" res += "-"
res += sub_elements_list[gp_id].phoneme res += sub_elements_list[gp_id].phoneme
@@ -195,13 +195,13 @@ func _on_validate_button_pressed() -> void:
func update_lesson() -> void: func update_lesson() -> void:
var m: = -1 var m: int = -1
for gp_id in gp_ids: for gp_id: int in gp_ids:
var i: = Database.get_min_lesson_for_gp_id(gp_id) var i: int = Database.get_min_lesson_for_gp_id(gp_id)
if i < 0: if i < 0:
m = -1 m = -1
break break
m = max(m, i) m = maxi(m, i)
lesson = m lesson = m
@@ -226,7 +226,7 @@ func insert_in_database() -> void:
id = Database.db.query_result[0].ID id = Database.db.query_result[0].ID
if id >= 0: if id >= 0:
var query: = "SELECT %s, group_concat(%s, ' ') as %ss, group_concat(%s, ' ') as %ss, group_concat(%s.ID, ' ') as %sIDs, group_concat(%s.ID, ' ') as %sIDs, %s.Exception, %s.Reading, %s.Writing var query: String = "SELECT %s, group_concat(%s, ' ') as %ss, group_concat(%s, ' ') as %ss, group_concat(%s.ID, ' ') as %sIDs, group_concat(%s.ID, ' ') as %sIDs, %s.Exception, %s.Reading, %s.Writing
FROM %s FROM %s
INNER JOIN ( SELECT * FROM %s ORDER BY %s.Position ) %s ON %s.ID = %s.%sID INNER JOIN ( SELECT * FROM %s ORDER BY %s.Position ) %s ON %s.ID = %s.%sID
INNER JOIN %s ON %s.ID = %s.%s INNER JOIN %s ON %s.ID = %s.%s
@@ -242,15 +242,15 @@ func insert_in_database() -> void:
Database.db.query_with_bindings(query, [id]) Database.db.query_with_bindings(query, [id])
Logger.trace("WordListElement: Sending query to insert in database: %s" % query) Logger.trace("WordListElement: Sending query to insert in database: %s" % query)
if not Database.db.query_result.is_empty(): if not Database.db.query_result.is_empty():
var e = Database.db.query_result[0] var element: Dictionary = Database.db.query_result[0]
if word != e[table_graph_column] or exception != e.Exception or reading != e.Reading or writing != e.Writing: if word != element[table_graph_column] or exception != element.Exception or reading != element.Reading or writing != element.Writing:
Database.db.update_rows(table, "ID=%s" % id, {table_graph_column: word, "Exception": exception, "Reading": reading, "Writing": writing}) Database.db.update_rows(table, "ID=%s" % id, {table_graph_column: word, "Exception": exception, "Reading": reading, "Writing": writing})
if " ".join(gp_ids) != e[sub_table + "IDs"]: if " ".join(gp_ids) != element[sub_table + "IDs"]:
var gps_in_words_ids: Array = Array(e[relational_table + "IDs"].split(" ")) var gps_in_words_ids: Array[String] = Array((element[relational_table + "IDs"] as String).split(" "))
while gps_in_words_ids.size() > gp_ids.size(): while gps_in_words_ids.size() > gp_ids.size():
Database.db.delete_rows(relational_table, "ID=%s" % int(gps_in_words_ids.pop_back())) Database.db.delete_rows(relational_table, "ID=%s" % int(gps_in_words_ids.pop_back() as String))
for index: int in gps_in_words_ids.size(): for index: int in gps_in_words_ids.size():
var gps_in_words_id: = int(gps_in_words_ids[index]) var gps_in_words_id: int = int(gps_in_words_ids[index])
Database.db.update_rows(relational_table, "ID=%s" % gps_in_words_id, { Database.db.update_rows(relational_table, "ID=%s" % gps_in_words_id, {
table_graph_column + "ID": id, table_graph_column + "ID": id,
sub_table_id: gp_ids[index], sub_table_id: gp_ids[index],
@@ -266,9 +266,9 @@ func insert_in_database() -> void:
else: else:
Database.db.query_with_bindings("SELECT * FROM %s WHERE %s=?" % [table, table_graph_column], [word]) Database.db.query_with_bindings("SELECT * FROM %s WHERE %s=?" % [table, table_graph_column], [word])
if not Database.db.query_result.is_empty(): if not Database.db.query_result.is_empty():
var e = Database.db.query_result[0] var element: Dictionary = Database.db.query_result[0]
id = e.ID id = element.ID
if word != e[table_graph_column] or exception != e.Exception or reading != e.Reading or writing != e.writing: if word != element[table_graph_column] or exception != element.Exception or reading != element.Reading or writing != element.writing:
Database.db.update_rows(table, "ID=%s" % id, {table_graph_column: word, "Exception": exception, "Reading": reading, "Writing": writing}) Database.db.update_rows(table, "ID=%s" % id, {table_graph_column: word, "Exception": exception, "Reading": reading, "Writing": writing})
for index: int in range(gp_ids.size()): for index: int in range(gp_ids.size()):
Database.db.insert_row(relational_table, { Database.db.insert_row(relational_table, {
@@ -290,7 +290,7 @@ func insert_in_database() -> void:
func _already_in_database(text: String) -> int: func _already_in_database(text: String) -> int:
var query: = "SELECT %s.ID, %s, group_concat(%s, ' ') as %ss, group_concat(%s, ' ') as %ss, group_concat(%s.ID, ' ') as %sIDs var query: String = "SELECT %s.ID, %s, group_concat(%s, ' ') as %ss, group_concat(%s, ' ') as %ss, group_concat(%s.ID, ' ') as %sIDs
FROM %s FROM %s
INNER JOIN ( SELECT * FROM %s ORDER BY %s.Position ) %s ON %s.ID = %s.%sID INNER JOIN ( SELECT * FROM %s ORDER BY %s.Position ) %s ON %s.ID = %s.%sID
INNER JOIN %s ON %s.ID = %s.%s INNER JOIN %s ON %s.ID = %s.%s
@@ -305,15 +305,15 @@ func _already_in_database(text: String) -> int:
table] table]
Database.db.query_with_bindings(query, [text]) Database.db.query_with_bindings(query, [text])
if not Database.db.query_result.is_empty(): if not Database.db.query_result.is_empty():
var e = Database.db.query_result[0] var element: Dictionary = Database.db.query_result[0]
id = e.ID id = element.ID
return id return id
return -1 return -1
func _add_from_additional_word_list(new_text: String) -> int: func _add_from_additional_word_list(new_text: String) -> int:
if new_text in Database.additional_word_list: if new_text in Database.additional_word_list:
var is_word: = table == "Words" var is_word: bool = table == "Words"
var res: Array = Database._import_word_from_csv(new_text, Database.additional_word_list[new_text].GPMATCH as String, is_word) var res: Array = Database._import_word_from_csv(new_text, Database.additional_word_list[new_text].GPMATCH as String, is_word)
GPs_updated.emit() GPs_updated.emit()
id = res[0] id = res[0]
@@ -355,14 +355,15 @@ func _process(_delta: float) -> void:
remove_gp_button.visible = graphemes_edit_container.get_child_count() > 0 remove_gp_button.visible = graphemes_edit_container.get_child_count() > 0
func new_gp_asked_added(ind: int, id: int) -> void: func new_gp_asked_added(ind: int, gp_id: int) -> void:
unvalidated_gp_ids[ind] = id unvalidated_gp_ids[ind] = gp_id
set_graphemes_edit(unvalidated_gp_ids) set_graphemes_edit(unvalidated_gp_ids)
word_edit.text = get_graphemes(unvalidated_gp_ids) word_edit.text = get_graphemes(unvalidated_gp_ids)
func _on_add_gp_button_pressed(element: Node) -> void: func _on_add_gp_button_pressed(element: Node) -> void:
var ind_gp_id: = element.get_index() / 2 @warning_ignore("integer_division")
var ind_gp_id: int = element.get_index() / 2
var gp_id: int = sub_elements_list.keys()[0] var gp_id: int = sub_elements_list.keys()[0]
unvalidated_gp_ids.insert(ind_gp_id + 1, gp_id) unvalidated_gp_ids.insert(ind_gp_id + 1, gp_id)
add_gp_list_button(gp_id, ind_gp_id + 1) add_gp_list_button(gp_id, ind_gp_id + 1)
+21 -21
View File
@@ -3,10 +3,10 @@ extends Path2D
signal finished signal finished
signal demo_finished signal demo_finished
@export var points_per_curve: = 25 @export var points_per_curve: int = 25
@export var hand_min_travel_time: = 0.5 @export var hand_min_travel_time: float = 0.5
@export var hand_max_travel_time: = 2.0 @export var hand_max_travel_time: float = 2.0
@export var distance: = 100.0 @export var distance: float = 100.0
@export var color_gradient: Gradient @export var color_gradient: Gradient
@@ -17,12 +17,12 @@ signal demo_finished
@onready var hand_sprite: Sprite2D = $HandPathFollow2D/Hand @onready var hand_sprite: Sprite2D = $HandPathFollow2D/Hand
var curve_points: PackedVector2Array var curve_points: PackedVector2Array
@onready var remaining_curve: = Curve2D.new() @onready var remaining_curve: Curve2D = Curve2D.new()
var is_playing: = false var is_playing: bool = false
var is_in_demo: = false var is_in_demo: bool = false
var touch_positions: = [] var touch_positions: Array[Vector2]
var should_play_effects: = false var should_play_effects: bool = false
func _ready() -> void: func _ready() -> void:
@@ -42,8 +42,8 @@ func _process(delta: float) -> void:
if is_playing or is_in_demo: if is_playing or is_in_demo:
var points: PackedVector2Array = [] var points: PackedVector2Array = []
for index: int in range(0, int(guide.progress), 10): for index: int in range(0, int(guide.progress), 10):
var i_f: = float(index) var i_f: float = float(index)
var point: = curve.sample_baked(i_f) var point: Vector2 = curve.sample_baked(i_f)
points.append(point) points.append(point)
line.points = points line.points = points
@@ -66,7 +66,7 @@ func _tracing_process() -> void:
while touch_positions.size() > 0: while touch_positions.size() > 0:
var touch_position: Vector2 = touch_positions.pop_front() var touch_position: Vector2 = touch_positions.pop_front()
var touch_vector: Vector2 = touch_position - guide.global_position var touch_vector: Vector2 = touch_position - guide.global_position
var current_offset: = 0.0 var current_offset: float = 0.0
if touch_vector.length() < distance: if touch_vector.length() < distance:
var target_offset: float = remaining_curve.get_closest_offset(touch_position - global_position) var target_offset: float = remaining_curve.get_closest_offset(touch_position - global_position)
if target_offset > current_offset and target_offset - current_offset <= distance: if target_offset > current_offset and target_offset - current_offset <= distance:
@@ -74,9 +74,9 @@ func _tracing_process() -> void:
line.default_color = color_gradient.sample(guide.progress_ratio) line.default_color = color_gradient.sample(guide.progress_ratio)
should_play_effects = true should_play_effects = true
var remove_up_to: = 0 var remove_up_to: int = 0
for index: int in curve_points.size(): for index: int in curve_points.size():
var offset: = curve.get_closest_offset(curve_points[index]) var offset: float = curve.get_closest_offset(curve_points[index])
if offset > guide.progress: if offset > guide.progress:
remove_up_to = index remove_up_to = index
break break
@@ -87,8 +87,8 @@ func _tracing_process() -> void:
func _hand_process(delta: float) -> void: func _hand_process(delta: float) -> void:
var current_progression: float = guide.progress_ratio var current_progression: float = guide.progress_ratio
var current_hand_travel_time: = current_progression * hand_min_travel_time + (1.0 - current_progression) * hand_max_travel_time var current_hand_travel_time: float = current_progression * hand_min_travel_time + (1.0 - current_progression) * hand_max_travel_time
var hand_speed: = (1.0 - current_progression) / current_hand_travel_time var hand_speed: float = (1.0 - current_progression) / current_hand_travel_time
hand.progress_ratio += delta * hand_speed hand.progress_ratio += delta * hand_speed
if hand.progress_ratio >= 1.0: if hand.progress_ratio >= 1.0:
@@ -105,7 +105,7 @@ func setup(points: Array) -> void:
curve.resource_local_to_scene = true curve.resource_local_to_scene = true
line.width = 50.0 line.width = 50.0
var smooth_points: = _smooth_points(points) var smooth_points: Array[Vector2] = _smooth_points(points)
for point: Vector2 in smooth_points: for point: Vector2 in smooth_points:
curve.add_point(point) curve.add_point(point)
@@ -115,12 +115,12 @@ func setup(points: Array) -> void:
curve_points = curve.get_baked_points() curve_points = curve.get_baked_points()
remaining_curve.clear_points() remaining_curve.clear_points()
for p in curve_points: for point: Vector2 in curve_points:
remaining_curve.add_point(p) remaining_curve.add_point(point)
func _smooth_points(points: Array) -> Array: func _smooth_points(points: Array) -> Array:
return Bezier.bezier_sampling(points, max(points_per_curve, points.size()) as int) return Bezier.bezier_sampling(points, maxi(points_per_curve, points.size()))
func set_points(points: Array) -> void: func set_points(points: Array) -> void:
@@ -165,7 +165,7 @@ func demo() -> void:
hand_sprite.visible = true hand_sprite.visible = true
hand.progress_ratio = 0.0 hand.progress_ratio = 0.0
var tween: = create_tween().set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_IN_OUT) var tween: Tween = create_tween().set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_IN_OUT)
tween.tween_property(hand, "progress_ratio", 1.0, hand_max_travel_time) tween.tween_property(hand, "progress_ratio", 1.0, hand_max_travel_time)
tween.tween_callback(demo_end) tween.tween_callback(demo_end)
+5 -5
View File
@@ -2,7 +2,7 @@
extends Control extends Control
const Gardens: = preload("res://sources/gardens/gardens.gd") const Gardens: = preload("res://sources/gardens/gardens.gd")
const gardens_scene: = preload("res://sources/gardens/gardens.tscn") const gardens_scene: PackedScene = preload("res://sources/gardens/gardens.tscn")
const Kalulu: = preload("res://sources/minigames/base/kalulu.gd") const Kalulu: = preload("res://sources/minigames/base/kalulu.gd")
@export var locked_color: Color @export var locked_color: Color
@@ -73,7 +73,7 @@ func _ready() -> void:
var lesson_ind: int = 1 var lesson_ind: int = 1
for index: int in range(gardens_layout.gardens.size()): for index: int in range(gardens_layout.gardens.size()):
var can_emit: = true var can_emit: bool = true
if UserDataManager.student_progression.unlocks.has(lesson_ind) and UserDataManager.student_progression.unlocks[lesson_ind]["look_and_learn"] != UserProgression.Status.Locked: if UserDataManager.student_progression.unlocks.has(lesson_ind) and UserDataManager.student_progression.unlocks[lesson_ind]["look_and_learn"] != UserProgression.Status.Locked:
garden_buttons[index].disabled = false garden_buttons[index].disabled = false
garden_buttons[index].self_modulate = unlocked_colors[index] garden_buttons[index].self_modulate = unlocked_colors[index]
@@ -82,8 +82,8 @@ func _ready() -> void:
garden_buttons[index].self_modulate = locked_color garden_buttons[index].self_modulate = locked_color
can_emit = false can_emit = false
var emitting: = false var emitting: bool = false
for _index2 in range(gardens_layout.gardens[index].lesson_buttons.size()): for _index2: int in range(gardens_layout.gardens[index].lesson_buttons.size()):
if can_emit and not emitting: if can_emit and not emitting:
emitting = false emitting = false
for game: UserProgression.Status in UserDataManager.student_progression.unlocks[lesson_ind]["games"]: for game: UserProgression.Status in UserDataManager.student_progression.unlocks[lesson_ind]["games"]:
@@ -101,7 +101,7 @@ func _ready() -> void:
_play_tutorial() _play_tutorial()
func _play_tutorial() -> void: func _play_tutorial() -> void:
var tutorial_count: = 0 var tutorial_count: int = 0
kalulu_button.hide() kalulu_button.hide()
while tutorial_count < tutorial_speeches.size(): while tutorial_count < tutorial_speeches.size():
@@ -4,7 +4,7 @@ extends Control
const DeviceButton:= preload("res://sources/menus/main/device_button.gd") const DeviceButton:= preload("res://sources/menus/main/device_button.gd")
const device_button_scene: PackedScene = preload("res://sources/menus/main/device_button.tscn") const device_button_scene: PackedScene = preload("res://sources/menus/main/device_button.tscn")
const login_scene_path := "res://sources/menus/login/login.tscn" const login_scene_path: String = "res://sources/menus/login/login.tscn"
@export var colors: Array[Color] @export var colors: Array[Color]
@@ -17,7 +17,7 @@ func _refresh() -> void:
if not UserDataManager.teacher_settings: if not UserDataManager.teacher_settings:
return return
for child in container.get_children(): for child: Node in container.get_children():
child.queue_free() child.queue_free()
for device: int in UserDataManager.teacher_settings.students.keys(): for device: int in UserDataManager.teacher_settings.students.keys():
@@ -53,7 +53,7 @@ func _ready() -> void:
return return
# Check the configuration # Check the configuration
var server_configuration: = await ServerManager.get_configuration() var server_configuration: Dictionary = await ServerManager.get_configuration()
if server_configuration.code == 401: if server_configuration.code == 401:
UserDataManager.logout() UserDataManager.logout()
_show_error(0) _show_error(0)
@@ -70,7 +70,7 @@ func _ready() -> void:
var current_version: Dictionary = UserDataManager.get_device_settings().language_versions.get(device_language, {}) var current_version: Dictionary = UserDataManager.get_device_settings().language_versions.get(device_language, {})
# Gets the info of the language pack on the server # Gets the info of the language pack on the server
var res: = await ServerManager.get_language_pack_url(device_language) var res: Dictionary = await ServerManager.get_language_pack_url(device_language)
if res.code == 200: if res.code == 200:
server_version = Time.get_datetime_dict_from_datetime_string(res.body.last_modified as String, false) server_version = Time.get_datetime_dict_from_datetime_string(res.body.last_modified as String, false)
# Authentication failed, disconnect the user # Authentication failed, disconnect the user
@@ -173,7 +173,7 @@ func _copy_data(this: PackageDownloader) -> void:
# Move the data to the locale folder of the user # Move the data to the locale folder of the user
var error: Error = DirAccess.rename_absolute(user_language_resources_path.path_join(subfolder), current_language_path) var error: Error = DirAccess.rename_absolute(user_language_resources_path.path_join(subfolder), current_language_path)
if error != null: if error != OK:
Logger.error("PackageDownloader: Error " + str(error) + " while renaming folder from %s to %s" % [user_language_resources_path.path_join(subfolder), current_language_path]) Logger.error("PackageDownloader: Error " + str(error) + " while renaming folder from %s to %s" % [user_language_resources_path.path_join(subfolder), current_language_path])
# Cleanup unnecessary files # Cleanup unnecessary files
@@ -217,9 +217,9 @@ func delete_directory_recursive(path: String) -> void:
func _delete_dir(path: String) -> void: func _delete_dir(path: String) -> void:
var dir: DirAccess = DirAccess.open(path) var dir: DirAccess = DirAccess.open(path)
for file in dir.get_files(): for file: String in dir.get_files():
dir.remove(file) dir.remove(file)
for subfolder in dir.get_directories(): for subfolder: String in dir.get_directories():
_delete_dir(path.path_join(subfolder)) _delete_dir(path.path_join(subfolder))
dir.remove(subfolder) dir.remove(subfolder)
+4 -4
View File
@@ -1,10 +1,10 @@
extends Control extends Control
const teacher_password : String = "42" const teacher_password : String = "42"
const back_scene_path: = "res://sources/menus/main/main_menu.tscn" const back_scene_path: String = "res://sources/menus/main/main_menu.tscn"
const next_scene_path: = "res://sources/menus/brain/brain.tscn" const next_scene_path: String = "res://sources/menus/brain/brain.tscn"
const teacher_scene_path: = "res://sources/menus/settings/teacher_settings.tscn" const teacher_scene_path: String = "res://sources/menus/settings/teacher_settings.tscn"
const package_loader_scene_path: = "res://sources/menus/language_selection/package_downloader.tscn" const package_loader_scene_path: String = "res://sources/menus/language_selection/package_downloader.tscn"
const Kalulu: = preload("res://sources/minigames/base/kalulu.gd") const Kalulu: = preload("res://sources/minigames/base/kalulu.gd")
+10 -6
View File
@@ -1,18 +1,22 @@
@tool @tool
extends TextureButton extends TextureButton
@onready var background: TextureRect = $Background
@onready var label: Label = $Label
@export_range(1, 99) var number: int: @export_range(1, 99) var number: int:
set(value): set(value):
number = value number = value
if $Label: if label:
$Label.text = str(value) label.text = str(value)
@export var background_color: Color: @export var background_color: Color:
set(value): set(value):
background_color = value background_color = value
if $Background: if background:
$Background.self_modulate = background_color background.self_modulate = background_color
func _ready() -> void: func _ready() -> void:
$Label.text = str(number) label.text = str(number)
$Background.self_modulate = background_color background.self_modulate = background_color
@@ -1,6 +1,6 @@
extends Step extends Step
@onready var type: = %TypeSelect @onready var type: ItemList = %TypeSelect
func _ready() -> void: func _ready() -> void:
type.add_item(tr("TEACHER")) type.add_item(tr("TEACHER"))
@@ -8,7 +8,7 @@ func _ready() -> void:
func _on_next() -> bool: func _on_next() -> bool:
var register_data = data as TeacherSettings var register_data: TeacherSettings = data as TeacherSettings
if register_data: if register_data:
if register_data.account_type == TeacherSettings.AccountType.Parent: if register_data.account_type == TeacherSettings.AccountType.Parent:
register_data.education_method = TeacherSettings.EducationMethod.AppOnly register_data.education_method = TeacherSettings.EducationMethod.AppOnly
@@ -51,11 +51,11 @@ theme_override_font_sizes/font_size = 70
allow_search = false allow_search = false
auto_height = true auto_height = true
[node name="ControlValidator" type="Node" parent="FormValidator/FormBinder/Control/Background/FormMargin/FormContainer/TypeContainer/VBoxContainer/TypeSelect" index="1"] [node name="ControlValidator" type="Node" parent="FormValidator/FormBinder/Control/Background/FormMargin/FormContainer/TypeContainer/VBoxContainer/TypeSelect" index="2"]
script = ExtResource("2_hidu6") script = ExtResource("2_hidu6")
validator = SubResource("Resource_n0ht0") validator = SubResource("Resource_n0ht0")
[node name="ControlBinder" type="Control" parent="FormValidator/FormBinder/Control/Background/FormMargin/FormContainer/TypeContainer/VBoxContainer/TypeSelect" index="2"] [node name="ControlBinder" type="Control" parent="FormValidator/FormBinder/Control/Background/FormMargin/FormContainer/TypeContainer/VBoxContainer/TypeSelect" index="3"]
layout_mode = 2 layout_mode = 2
anchors_preset = 0 anchors_preset = 0
offset_left = -548.0 offset_left = -548.0
+2 -2
View File
@@ -14,7 +14,7 @@ signal next(step : Step)
@export var step_name : String @export var step_name : String
@export_multiline var question : String @export_multiline var question : String
@export_multiline var infos : String @export_multiline var infos : String
@export var data : Resource @export var data : TeacherSettings
func on_enter() -> void: func on_enter() -> void:
form_binder.read(data) form_binder.read(data)
@@ -33,7 +33,7 @@ func _on_next() -> bool:
return true return true
# Display error messages # Display error messages
func _on_form_validator_control_validated(control, passed, messages) -> void: func _on_form_validator_control_validated(control: ItemList, passed: bool, messages: PackedStringArray) -> void:
var label: Label = find_child(control.name as String + "Error", true, false) as Label var label: Label = find_child(control.name as String + "Error", true, false) as Label
if not label: if not label:
return return
@@ -15,7 +15,7 @@ func _on_validate_button_pressed() -> void:
Logger.warn("CredentialsStep: Impossible to write data in object (" + str(self) + ")") Logger.warn("CredentialsStep: Impossible to write data in object (" + str(self) + ")")
return return
var res = await ServerManager.check_email(data.email) var res: Dictionary = await ServerManager.check_email(data.email as String)
if res.code != 200: if res.code != 200:
api_email_field_error.visible = true api_email_field_error.visible = true
return return
+6 -6
View File
@@ -1,6 +1,6 @@
extends Step extends Step
class_name RecapStep
const DeviceRecap: = preload("res://sources/menus/register/steps/device_recap.gd")
const device_recap_scene : PackedScene = preload("res://sources/menus/register/steps/device_recap.tscn") const device_recap_scene : PackedScene = preload("res://sources/menus/register/steps/device_recap.tscn")
@onready var recap_container : VBoxContainer = %RecapContainer @onready var recap_container : VBoxContainer = %RecapContainer
@@ -13,15 +13,15 @@ const device_recap_scene : PackedScene = preload("res://sources/menus/register/s
func on_enter() -> void: func on_enter() -> void:
super.on_enter() super.on_enter()
var teacher_settings = data as TeacherSettings var teacher_settings: TeacherSettings = data as TeacherSettings
if not teacher_settings: if not teacher_settings:
return return
email.text = tr("SUMMARY_EMAIL").format({"mail" : teacher_settings.email}) email.text = tr("SUMMARY_EMAIL").format({"mail" : teacher_settings.email})
account_type.text = tr("SUMMARY_TYPE").format({"type" : tr(TeacherSettings.AccountType.keys()[teacher_settings.account_type].to_upper())}) account_type.text = tr("SUMMARY_TYPE").format({"type" : tr((TeacherSettings.AccountType.keys()[teacher_settings.account_type] as String).to_upper())})
if teacher_settings.account_type == TeacherSettings.AccountType.Teacher: if teacher_settings.account_type == TeacherSettings.AccountType.Teacher:
education_method.text = tr("SUMMARY_METHOD").format({"method" : tr(TeacherSettings.EducationMethod.keys()[teacher_settings.education_method].to_upper())}) education_method.text = tr("SUMMARY_METHOD").format({"method" : tr((TeacherSettings.EducationMethod.keys()[teacher_settings.education_method] as String).to_upper())})
education_method.show() education_method.show()
devices_count.text = tr("SUMMARY_NUMBER_OF_DEVICES").format({"number" : teacher_settings.students.size()}) devices_count.text = tr("SUMMARY_NUMBER_OF_DEVICES").format({"number" : teacher_settings.students.size()})
@@ -34,10 +34,10 @@ func on_enter() -> void:
devices_count.hide() devices_count.hide()
students_count.hide() students_count.hide()
for child in recap_container.get_children(false): for child: Node in recap_container.get_children(false):
child.queue_free() child.queue_free()
for device in teacher_settings.students.keys(): for device: int in teacher_settings.students.keys():
var device_recap : DeviceRecap = device_recap_scene.instantiate() var device_recap : DeviceRecap = device_recap_scene.instantiate()
if teacher_settings.account_type == TeacherSettings.AccountType.Teacher: if teacher_settings.account_type == TeacherSettings.AccountType.Teacher:
@@ -48,11 +48,11 @@ item_0/text = "METHOD_APP_ONLY"
item_1/text = "METHOD_COMPLETE" item_1/text = "METHOD_COMPLETE"
script = ExtResource("2_qrbn1") script = ExtResource("2_qrbn1")
[node name="ControlValidator" type="Node" parent="FormValidator/FormBinder/Control/Background/FormMargin/FormContainer/MethodContainer/VBoxContainer/MethodSelect" index="1"] [node name="ControlValidator" type="Node" parent="FormValidator/FormBinder/Control/Background/FormMargin/FormContainer/MethodContainer/VBoxContainer/MethodSelect" index="2"]
script = ExtResource("2_03dua") script = ExtResource("2_03dua")
validator = SubResource("Resource_ar6ux") validator = SubResource("Resource_ar6ux")
[node name="ControlBinder" type="Control" parent="FormValidator/FormBinder/Control/Background/FormMargin/FormContainer/MethodContainer/VBoxContainer/MethodSelect" index="2"] [node name="ControlBinder" type="Control" parent="FormValidator/FormBinder/Control/Background/FormMargin/FormContainer/MethodContainer/VBoxContainer/MethodSelect" index="3"]
layout_mode = 2 layout_mode = 2
anchors_preset = 0 anchors_preset = 0
offset_top = 236.0 offset_top = 236.0
@@ -2,10 +2,10 @@ extends Step
class_name StudentsCountStep class_name StudentsCountStep
@export var device_id : int @export var device_id : int
@onready var students_count_field := %StudentsCountField @onready var students_count_field: SpinBox = %StudentsCountField
func _on_back() -> bool: func _on_back() -> bool:
var register_data = data as TeacherSettings var register_data: TeacherSettings = data as TeacherSettings
if register_data: if register_data:
register_data.students.erase(device_id) register_data.students.erase(device_id)
return true return true
@@ -13,13 +13,13 @@ func _on_back() -> bool:
func _on_next() -> bool: func _on_next() -> bool:
var register_data = data as TeacherSettings var register_data: TeacherSettings = data as TeacherSettings
if register_data: if register_data:
var students : Array[StudentData] = [] var students: Array[StudentData] = []
register_data.students[device_id] = students register_data.students[device_id] = students
for student in students_count_field.value: for _student: int in students_count_field.value:
var student_data = StudentData.new() var student_data: StudentData = StudentData.new()
student_data.code = register_data.get_new_code() student_data.code = int(register_data.get_new_code())
if student_data.code: if student_data.code:
students.append(student_data) students.append(student_data)
else: else:
@@ -9,7 +9,7 @@ func _init() -> void:
func apply(control: Control, value) -> RuleResult: func apply(control: Control, value) -> RuleResult:
var result = RuleResult.new() var result: RuleResult = RuleResult.new()
if confirm_control_path && value is String: if confirm_control_path && value is String:
var confirm_control = control.get_child(0).get_node(confirm_control_path) var confirm_control = control.get_child(0).get_node(confirm_control_path)
result.passed = confirm_control && Validation.find_validator(control).get_value(confirm_control) == value result.passed = confirm_control && Validation.find_validator(control).get_value(confirm_control) == value
@@ -4,11 +4,11 @@ class_name ItemListValidator
func get_value(control: Control) -> Variant: func get_value(control: Control) -> Variant:
var item_list = control as ItemList var item_list: ItemList = control as ItemList
if not item_list: if not item_list:
return null return null
var selected_indexes = item_list.get_selected_items() var selected_indexes: PackedInt32Array = item_list.get_selected_items()
if not selected_indexes or selected_indexes.size() == 0: if not selected_indexes or selected_indexes.size() == 0:
return null return null
@@ -18,5 +18,5 @@ func get_value(control: Control) -> Variant:
return selected_indexes return selected_indexes
func is_type(node) -> bool: func is_type(node: Node) -> bool:
return node is ItemList return node is ItemList
+5 -5
View File
@@ -4,7 +4,7 @@ class_name LessonUnlocks
signal student_deleted(code: int) signal student_deleted(code: int)
const StudentUnlock: = preload("res://sources/menus/settings/lesson_unlock.gd") const StudentUnlock: = preload("res://sources/menus/settings/lesson_unlock.gd")
const student_unlock_scene: = preload("res://sources/menus/settings/lesson_unlock.tscn") const student_unlock_scene: PackedScene = preload("res://sources/menus/settings/lesson_unlock.tscn")
@onready var lesson_container: VBoxContainer = %LessonContainer @onready var lesson_container: VBoxContainer = %LessonContainer
@@ -15,7 +15,7 @@ const student_unlock_scene: = preload("res://sources/menus/settings/lesson_unloc
var progression: UserProgression var progression: UserProgression
func _create_lessons() -> void: func _create_lessons() -> void:
for lesson_unlock in lesson_container.get_children(): for lesson_unlock: Node in lesson_container.get_children():
lesson_unlock.queue_free() lesson_unlock.queue_free()
Database.db.query("SELECT LessonNb, group_concat(Grapheme || '-' ||Phoneme, ' ') GPs FROM Lessons Database.db.query("SELECT LessonNb, group_concat(Grapheme || '-' ||Phoneme, ' ') GPs FROM Lessons
@@ -23,10 +23,10 @@ INNER JOIN GPsInLessons ON GPsInLessons.LessonID = Lessons.ID
INNER JOIN GPs ON GPsInLessons.GPID = GPs.ID INNER JOIN GPs ON GPsInLessons.GPID = GPs.ID
GROUP BY LessonNb GROUP BY LessonNb
ORDER BY LessonNb") ORDER BY LessonNb")
for e in Database.db.query_result: for element: Dictionary in Database.db.query_result:
var student_unlock: StudentUnlock = student_unlock_scene.instantiate() var student_unlock: StudentUnlock = student_unlock_scene.instantiate()
student_unlock.lesson_GPs = e.GPs student_unlock.lesson_GPs = element.GPs
student_unlock.lesson_number = e.LessonNb student_unlock.lesson_number = element.LessonNb
student_unlock.unlocks = progression.unlocks student_unlock.unlocks = progression.unlocks
lesson_container.add_child(student_unlock) lesson_container.add_child(student_unlock)
+7 -7
View File
@@ -16,7 +16,7 @@ const device_tab_scene: PackedScene = preload("res://sources/menus/settings/devi
@onready var add_student_popup: CanvasLayer = %AddStudentPopup @onready var add_student_popup: CanvasLayer = %AddStudentPopup
@onready var delete_student_popup: CanvasLayer = %DeleteStudentPopup @onready var delete_student_popup: CanvasLayer = %DeleteStudentPopup
var last_device_id: = -1 var last_device_id: int = -1
func _ready() -> void: func _ready() -> void:
_refresh_devices_tabs() _refresh_devices_tabs()
@@ -32,7 +32,7 @@ func _ready() -> void:
func _refresh_devices_tabs() -> void: func _refresh_devices_tabs() -> void:
for child in devices_tab_container.get_children(false): for child: Node in devices_tab_container.get_children(false):
child.queue_free() child.queue_free()
if not UserDataManager.teacher_settings: if not UserDataManager.teacher_settings:
@@ -90,11 +90,11 @@ func _on_add_student_button_pressed() -> void:
func _on_add_student_popup_accepted() -> void: func _on_add_student_popup_accepted() -> void:
var current_tab: = devices_tab_container.get_current_tab_control() as DeviceTab var current_tab: DeviceTab = devices_tab_container.get_current_tab_control() as DeviceTab
if not current_tab: if not current_tab:
Logger.error("TeacherSettings: DeviceTab not found") Logger.error("TeacherSettings: DeviceTab not found")
return return
var res: = await ServerManager.add_student({"device" : current_tab.device_id}) var res: Dictionary = await ServerManager.add_student({"device" : current_tab.device_id})
if res.code == 200: if res.code == 200:
UserDataManager.update_configuration(res.body as Dictionary) UserDataManager.update_configuration(res.body as Dictionary)
current_tab.students = UserDataManager.teacher_settings.students[current_tab.device_id] current_tab.students = UserDataManager.teacher_settings.students[current_tab.device_id]
@@ -108,7 +108,7 @@ func _on_add_device_button_pressed() -> void:
func _on_add_device_popup_accepted() -> void: func _on_add_device_popup_accepted() -> void:
var res: = await ServerManager.add_student({"device" : last_device_id + 1}) var res: Dictionary = await ServerManager.add_student({"device" : last_device_id + 1})
if res.code == 200: if res.code == 200:
UserDataManager.update_configuration(res.body as Dictionary) UserDataManager.update_configuration(res.body as Dictionary)
_refresh_devices_tabs() _refresh_devices_tabs()
@@ -120,10 +120,10 @@ func _on_lesson_unlocks_student_deleted(_code: int) -> void:
func _on_delete_student_popup_accepted() -> void: func _on_delete_student_popup_accepted() -> void:
var current_tab: = devices_tab_container.get_current_tab_control() as DeviceTab var current_tab: DeviceTab = devices_tab_container.get_current_tab_control() as DeviceTab
if not current_tab: if not current_tab:
return return
var res: = await ServerManager.remove_student(int(lesson_unlocks.student)) var res: Dictionary = await ServerManager.remove_student(int(lesson_unlocks.student))
if res.code == 200: if res.code == 200:
lesson_unlocks.hide() lesson_unlocks.hide()
UserDataManager.update_configuration(res.body as Dictionary) UserDataManager.update_configuration(res.body as Dictionary)
+1 -1
View File
@@ -263,7 +263,7 @@ func _lose() -> void:
_reset() _reset()
func _submit_student_metrics() -> void: func _submit_student_metrics() -> void:
var elapsed_time := Time.get_ticks_msec() / 1000.0 - _start_time - _elapsed_paused var elapsed_time: int = int(Time.get_ticks_msec() / 1000.0 - _start_time - _elapsed_paused)
ServerManager.submit_student_metrics(lesson_nb, elapsed_time) ServerManager.submit_student_metrics(lesson_nb, elapsed_time)
#endregion #endregion
@@ -30,12 +30,12 @@ func _start() -> void:
# Find the stimuli and distractions of the minigame. # Find the stimuli and distractions of the minigame.
# For this type of minigame, only vowels and syllables are allowed # For this type of minigame, only vowels and syllables are allowed
func _find_stimuli_and_distractions() -> void: func _find_stimuli_and_distractions() -> void:
var all_syllables: = Database.get_syllables_for_lesson(lesson_nb, false) var all_syllables: Array[Dictionary] = Database.get_syllables_for_lesson(lesson_nb, false)
if not all_syllables: if not all_syllables:
return return
var current_lesson_stimuli: Array[Dictionary] = [] var current_lesson_stimuli: Array[Dictionary]
var previous_lesson_stimuli: Array[Dictionary] = [] var previous_lesson_stimuli: Array[Dictionary]
# Find the syllables for current lesson # Find the syllables for current lesson
for syllable: Dictionary in all_syllables: for syllable: Dictionary in all_syllables:
@@ -99,7 +99,7 @@ func _find_stimuli_and_distractions() -> void:
# Any previously learned item w/ all letters different # Any previously learned item w/ all letters different
for syllable: Dictionary in all_syllables: for syllable: Dictionary in all_syllables:
if syllable.Phoneme != stimulus.Phoneme: if syllable.Phoneme != stimulus.Phoneme:
var gp_found_in_stimuli: = false var gp_found_in_stimuli: bool = false
for gp: Dictionary in syllable.GPs: for gp: Dictionary in syllable.GPs:
if gp in stimulus.GPs: if gp in stimulus.GPs:
gp_found_in_stimuli = true gp_found_in_stimuli = true
@@ -152,7 +152,7 @@ func _is_stimulus_right(stimulus : Dictionary) -> bool:
# Play the phoneme of the current stimulus # Play the phoneme of the current stimulus
func _play_current_stimulus_phoneme() -> void: func _play_current_stimulus_phoneme() -> void:
var current_stimulus: = _get_current_stimulus() var current_stimulus: Dictionary = _get_current_stimulus()
if not current_stimulus or not current_stimulus.has("Phoneme"): if not current_stimulus or not current_stimulus.has("Phoneme"):
return return
@@ -165,7 +165,7 @@ func _play_current_stimulus_phoneme() -> void:
func _await_for_future_or_stimulus_found(future : Signal) -> bool: func _await_for_future_or_stimulus_found(future : Signal) -> bool:
var coroutine: = Coroutine.new() var coroutine: Coroutine = Coroutine.new()
coroutine.add_future(_is_stimulus_found) coroutine.add_future(_is_stimulus_found)
coroutine.add_future(future) coroutine.add_future(future)
await coroutine.join_either() await coroutine.join_either()
+1 -1
View File
@@ -40,7 +40,7 @@ func fall() -> void:
return return
collision_shape.set_deferred("disabled", true) collision_shape.set_deferred("disabled", true)
await get_tree().create_timer(randf_range(0., 0.1)).timeout await get_tree().create_timer(randf_range(0., 0.1)).timeout
var tween: = get_tree().create_tween() var tween: Tween = get_tree().create_tween()
tween.tween_property(path_follow, "progress_ratio", 1, 2) tween.tween_property(path_follow, "progress_ratio", 1, 2)
+2 -2
View File
@@ -16,7 +16,7 @@ const berry_scene: PackedScene = preload("res://sources/minigames/caterpillar/be
@onready var leaf_timer: Timer = $LeafTimer @onready var leaf_timer: Timer = $LeafTimer
var velocity: float = 0.0 var velocity: float = 0.0
var is_highlighting: = false: var is_highlighting: bool = false:
set = _set_highlighting set = _set_highlighting
var is_running: float = true var is_running: float = true
@@ -30,7 +30,7 @@ func _set_highlighting(value: bool) -> void:
func _ready() -> void: func _ready() -> void:
# Adds some leaves from start # Adds some leaves from start
var pos: = -leaves.position.x + velocity * randf_range(0,2) var pos: float = -leaves.position.x + velocity * randf_range(0,2)
while pos < 0: while pos < 0:
var leaf: Leaf = leaf_scene.instantiate() var leaf: Leaf = leaf_scene.instantiate()
leaves.add_child(leaf) leaves.add_child(leaf)
+7 -7
View File
@@ -37,7 +37,7 @@ func move(y : float) -> void:
idle() idle()
is_moving = true is_moving = true
var coroutine: = Coroutine.new() var coroutine: Coroutine = Coroutine.new()
# Move head # Move head
coroutine.add_future(_tween_body_part(head, y).finished) coroutine.add_future(_tween_body_part(head, y).finished)
@@ -58,7 +58,7 @@ func move(y : float) -> void:
func _tween_body_part(part: Node2D, y: float) -> Tween: func _tween_body_part(part: Node2D, y: float) -> Tween:
var tween: = create_tween() var tween: Tween = create_tween()
tween.tween_property(part, "global_position:y", y, body_part_move_time) tween.tween_property(part, "global_position:y", y, body_part_move_time)
return tween return tween
@@ -67,11 +67,11 @@ func eat_berry(berry: Berry) -> void:
is_eating = true is_eating = true
var body_part: CaterpillarBody var body_part: CaterpillarBody
var tween: = create_tween() var tween: Tween = create_tween()
# Check if there is only one empty body part # Check if there is only one empty body part
if body_parts.get_child_count() == 1: if body_parts.get_child_count() == 1:
var current_body_part: = body_parts.get_child(0) as CaterpillarBody var current_body_part: CaterpillarBody = body_parts.get_child(0) as CaterpillarBody
if not current_body_part.gp: if not current_body_part.gp:
body_part = current_body_part body_part = current_body_part
@@ -109,7 +109,7 @@ func spit_berry(berry: Berry) -> void:
var pos_x : float = berry.global_position.x var pos_x : float = berry.global_position.x
# Eat the berry # Eat the berry
var tween: = create_tween() var tween: Tween = create_tween()
tween.tween_property(berry, "global_position:x",head.global_position.x + body_part_width * 2, .2) tween.tween_property(berry, "global_position:x",head.global_position.x + body_part_width * 2, .2)
await head.eat() await head.eat()
@@ -130,7 +130,7 @@ func spit_berry(berry: Berry) -> void:
func reset() -> void: func reset() -> void:
# Move the head and the body parts back # Move the head and the body parts back
var tween: = create_tween() var tween: Tween = create_tween()
tween.tween_property(head, "position:x", 0, 0.2) tween.tween_property(head, "position:x", 0, 0.2)
for index: int in range(1, body_parts.get_child_count()): for index: int in range(1, body_parts.get_child_count()):
@@ -149,6 +149,6 @@ func reset() -> void:
func _on_eat_area_2d_area_entered(area: Area2D) -> void: func _on_eat_area_2d_area_entered(area: Area2D) -> void:
if area is Berry and !is_moving: if area is Berry and !is_moving:
var berry: = area as Berry var berry: Berry = area as Berry
berry.is_eaten = true berry.is_eaten = true
berry_eaten.emit(berry) berry_eaten.emit(berry)
@@ -6,14 +6,14 @@ const Caterpillar: = preload("res://sources/minigames/caterpillar/caterpillar.gd
const Branch: = preload("res://sources/minigames/caterpillar/branch.gd") const Branch: = preload("res://sources/minigames/caterpillar/branch.gd")
const Berry: = preload("res://sources/minigames/caterpillar/berry.gd") const Berry: = preload("res://sources/minigames/caterpillar/berry.gd")
const branch_scene: = preload("res://sources/minigames/caterpillar/branch.tscn") const branch_scene: PackedScene = preload("res://sources/minigames/caterpillar/branch.tscn")
class DifficultySettings: class DifficultySettings:
var branches: = 2 var branches: int = 2
var stimuli_ratio: = 0.75 var stimuli_ratio: float = 0.75
var velocity: = 400. var velocity: float = 400.
var spawn_rate: = 3. var spawn_rate: float = 3.
func _init(p_branches: int, p_stimuli_ratio: float, p_velocity: float, p_spawn_rate: float) -> void: func _init(p_branches: int, p_stimuli_ratio: float, p_velocity: float, p_spawn_rate: float) -> void:
branches = p_branches branches = p_branches
@@ -126,7 +126,7 @@ func _on_berry_timer_timeout() -> void:
# Define if the berry is a stimulus or a distraction # Define if the berry is a stimulus or a distraction
var gp: Dictionary var gp: Dictionary
var is_stimulus: = randf() < _get_difficulty_settings().stimuli_ratio var is_stimulus: bool = randf() < _get_difficulty_settings().stimuli_ratio
if is_stimulus: if is_stimulus:
gp = _get_GP() gp = _get_GP()
else: else:
+2 -2
View File
@@ -49,12 +49,12 @@ func is_button_pressed() -> bool:
func show_label() -> void: func show_label() -> void:
var tween: = create_tween() var tween: Tween = create_tween()
tween.tween_property(label, "modulate:a", 1, .5) tween.tween_property(label, "modulate:a", 1, .5)
func hide_label() -> void: func hide_label() -> void:
var tween: = create_tween() var tween: Tween = create_tween()
tween.tween_property(label, "modulate:a", 0, .5) tween.tween_property(label, "modulate:a", 0, .5)
+13 -14
View File
@@ -2,14 +2,13 @@
extends SyllablesMinigame extends SyllablesMinigame
# Namespace # Namespace
const Hole: = preload("res://sources/minigames/crabs/hole/hole.gd")
const Crab: = preload("res://sources/minigames/crabs/crab/crab.gd") const Crab: = preload("res://sources/minigames/crabs/crab/crab.gd")
const hole_scene: = preload("res://sources/minigames/crabs/hole/hole.tscn") const hole_scene: PackedScene = preload("res://sources/minigames/crabs/hole/hole.tscn")
class DifficultySettings: class DifficultySettings:
var stimuli_ratio: = 0.75 var stimuli_ratio: float = 0.75
var rows: = [2, 1] var rows: Array[int] = [2, 1]
func _init(p_stimuli_ratio: float, p_rows: Array[int]) -> void: func _init(p_stimuli_ratio: float, p_rows: Array[int]) -> void:
stimuli_ratio = p_stimuli_ratio stimuli_ratio = p_stimuli_ratio
@@ -36,16 +35,16 @@ var stimulus_spawned: bool = false
func _setup_minigame() -> void: func _setup_minigame() -> void:
super._setup_minigame() super._setup_minigame()
var settings: = _get_difficulty_settings() var settings: DifficultySettings = _get_difficulty_settings()
# Spawns the good amount of holes and places them # Spawns the good amount of holes and places them
var top_left: Vector2 = crab_zone.position var top_left: Vector2 = crab_zone.position
var bottom_right: Vector2 = top_left + crab_zone.size var bottom_right: Vector2 = top_left + crab_zone.size
for index: int in range(settings.rows.size()): for index: int in range(settings.rows.size()):
var fi: = float(index + 1.0) / float(settings.rows.size() + 1.0) var fi: float = float(index + 1.0) / float(settings.rows.size() + 1.0)
var y: float = (1.0 - fi) * top_left.y + fi * bottom_right.y var y: float = (1.0 - fi) * top_left.y + fi * bottom_right.y
for j: int in range(settings.rows[index]): for j: int in range(settings.rows[index]):
var fj: = float(j + 1.0) / float(settings.rows[index] as int + 1.0) var fj: float = float(j + 1.0) / float(settings.rows[index] as int + 1.0)
var x: float = fj * top_left.x + (1.0 - fj) * bottom_right.x var x: float = fj * top_left.x + (1.0 - fj) * bottom_right.x
var hole: Hole = hole_scene.instantiate() var hole: Hole = hole_scene.instantiate()
@@ -72,7 +71,7 @@ func _get_difficulty_settings() -> DifficultySettings:
func _highlight() -> void: func _highlight() -> void:
for hole in holes: for hole: Hole in holes:
if hole.crab and hole.crab_visible and _is_stimulus_right(hole.crab.stimulus): if hole.crab and hole.crab_visible and _is_stimulus_right(hole.crab.stimulus):
hole.highlight() hole.highlight()
@@ -81,11 +80,11 @@ func _on_stimulus_pressed(stimulus: Dictionary, node: Node) -> bool:
if not super(stimulus, node): if not super(stimulus, node):
return false return false
var hole: = node as Hole var hole: Hole = node as Hole
if not hole: if not hole:
return false return false
var is_right: = _is_stimulus_right(stimulus) var is_right: bool = _is_stimulus_right(stimulus)
if is_right: if is_right:
hole.right() hole.right()
current_progression += 1 current_progression += 1
@@ -138,16 +137,16 @@ func _on_hole_crab_despawned(is_stimulus: bool) -> void:
func _on_hole_timer_timeout() -> void: func _on_hole_timer_timeout() -> void:
var holes_range: = range(holes.size()) var holes_range: Array[int] = range(holes.size())
holes_range.shuffle() holes_range.shuffle()
var hole_found: = false var hole_found: bool = false
while not hole_found: while not hole_found:
for index: int in holes_range: for index: int in holes_range:
if not holes[index].crab: if not holes[index].crab:
# Define if the crab is a stimulus or a distraction # Define if the crab is a stimulus or a distraction
# Only one crab with the correct stimulus can be showned at a time # Only one crab with the correct stimulus can be showned at a time
var is_stimulus: = not stimulus_spawned and randf() < _get_difficulty_settings().stimuli_ratio var is_stimulus: bool = not stimulus_spawned and randf() < _get_difficulty_settings().stimuli_ratio
if is_stimulus: if is_stimulus:
stimulus_spawned = true stimulus_spawned = true
holes[index].spawn_crab(_get_current_stimulus(), true) holes[index].spawn_crab(_get_current_stimulus(), true)
@@ -164,5 +163,5 @@ func _on_hole_timer_timeout() -> void:
func _on_stimulus_found() -> void: func _on_stimulus_found() -> void:
# Despawn all the crabs # Despawn all the crabs
for hole in holes: for hole: Hole in holes:
hole.stop.emit() hole.stop.emit()
+6 -5
View File
@@ -1,4 +1,5 @@
extends Node2D extends Node2D
class_name Hole
signal stimulus_hit(stimulus: Dictionary) signal stimulus_hit(stimulus: Dictionary)
signal crab_despawned(is_stimulus: bool) signal crab_despawned(is_stimulus: bool)
@@ -10,7 +11,7 @@ signal crab_out(hole)
const Crab: = preload("res://sources/minigames/crabs/crab/crab.gd") const Crab: = preload("res://sources/minigames/crabs/crab/crab.gd")
const CrabAudioStreamPlayer: = preload("res://sources/minigames/crabs/hole/hole_audio_stream_player_2d.gd") const CrabAudioStreamPlayer: = preload("res://sources/minigames/crabs/hole/hole_audio_stream_player_2d.gd")
const crab_scene: = preload("res://sources/minigames/crabs/crab/crab.tscn") const crab_scene: PackedScene = preload("res://sources/minigames/crabs/crab/crab.tscn")
@onready var hole_back: Sprite2D = $HoleBack @onready var hole_back: Sprite2D = $HoleBack
@onready var hole_front: Sprite2D = $HoleFront @onready var hole_front: Sprite2D = $HoleFront
@@ -79,7 +80,7 @@ func spawn_crab(gp: Dictionary, p_is_stimulus: bool) -> void:
crab.stimulus = gp crab.stimulus = gp
# Show the crab but not the stimulus # Show the crab but not the stimulus
var tween: = create_tween() var tween: Tween = create_tween()
tween.tween_property(crab, "position", Vector2(crab_x, -crab.size.y/7), randf_range(0.25, 2.0)) tween.tween_property(crab, "position", Vector2(crab_x, -crab.size.y/7), randf_range(0.25, 2.0))
if await is_button_pressed_with_limit(tween.finished): if await is_button_pressed_with_limit(tween.finished):
return return
@@ -116,7 +117,7 @@ func spawn_crab(gp: Dictionary, p_is_stimulus: bool) -> void:
func is_button_pressed_with_limit(future : Signal) -> bool: func is_button_pressed_with_limit(future : Signal) -> bool:
var coroutine: = Coroutine.new() var coroutine: Coroutine = Coroutine.new()
coroutine.add_future(crab.is_button_pressed) coroutine.add_future(crab.is_button_pressed)
coroutine.add_future(_is_stopped) coroutine.add_future(_is_stopped)
coroutine.add_future(future) coroutine.add_future(future)
@@ -131,7 +132,7 @@ func is_button_pressed_with_limit(future : Signal) -> bool:
if coroutine.return_value[1]: if coroutine.return_value[1]:
# Make the crab disappear in the hole # Make the crab disappear in the hole
var tween: = create_tween() var tween: Tween = create_tween()
tween.tween_property(crab, "position", Vector2(crab_x, crab.size.y / 2), 0.5) tween.tween_property(crab, "position", Vector2(crab_x, crab.size.y / 2), 0.5)
await tween.finished await tween.finished
@@ -170,7 +171,7 @@ func _on_crab_hit(stimulus: Dictionary) -> void:
stimulus_hit.emit(stimulus) stimulus_hit.emit(stimulus)
# Move the crab up and rotate # Move the crab up and rotate
var tween: = create_tween() var tween: Tween = create_tween()
tween.tween_property(crab, "position", Vector2(crab_x, -crab.size.y * 1.5), 1) tween.tween_property(crab, "position", Vector2(crab_x, -crab.size.y * 1.5), 1)
tween.parallel().tween_property(crab.body, "rotation_degrees", 900.0, 1) tween.parallel().tween_property(crab.body, "rotation_degrees", 900.0, 1)
await tween.finished await tween.finished
@@ -16,7 +16,7 @@ const crab_sound_list: Array[AudioStreamMP3] = [
preload("res://assets/minigames/crabs/audio/sfx/crab_random_1.mp3"), preload("res://assets/minigames/crabs/audio/sfx/crab_random_1.mp3"),
] ]
var _should_play: = false var _should_play: bool = false
func start_playing() -> void: func start_playing() -> void:
+16 -16
View File
@@ -2,7 +2,7 @@ extends Minigame
signal beacon_fish_dropped(is_answered_real: bool) signal beacon_fish_dropped(is_answered_real: bool)
const fish_texture_rect_scene: = preload("res://sources/minigames/fish/fish_texture_rect.tscn") const fish_texture_rect_scene: PackedScene = preload("res://sources/minigames/fish/fish_texture_rect.tscn")
@onready var fish_start_zone: Control = %FishStartZone @onready var fish_start_zone: Control = %FishStartZone
@onready var beacon1: SpriteControl = %Beacon1 @onready var beacon1: SpriteControl = %Beacon1
@@ -19,17 +19,17 @@ const fish_texture_rect_scene: = preload("res://sources/minigames/fish/fish_text
@onready var progress_gauge_internal: NinePatchRect = %ProgressionGaugeInternal @onready var progress_gauge_internal: NinePatchRect = %ProgressionGaugeInternal
@export var game_duration: = 4 * 60 @export var game_duration: int = 4 * 60
@export var minimum_correct_ratio: = 0.8 @export var minimum_correct_ratio: float = 0.8
@export var winning_color: = Color.WHITE @export var winning_color: Color = Color.WHITE
@export var max_words_count: = 15 @export var max_words_count: int = 15
var tween: Tween var tween: Tween
var words_to_present: Array[String] = [] var words_to_present: Array[String] = []
var words_to_present_next: Array[String] = [] var words_to_present_next: Array[String] = []
var progress_gauge_max_margin: = 0.95 var progress_gauge_max_margin: float = 0.95
var total_number_of_words: = 30 var total_number_of_words: int = 30
var tutorial_count: = 0 var tutorial_count: int = 0
func _fish_get_drag_data(_at_position: Vector2) -> Variant: func _fish_get_drag_data(_at_position: Vector2) -> Variant:
@@ -56,7 +56,7 @@ func _ready() -> void:
func _find_stimuli_and_distractions() -> void: func _find_stimuli_and_distractions() -> void:
var data_array: = Database.get_pseudowords_for_lesson(lesson_nb) var data_array: Array[Dictionary] = Database.get_pseudowords_for_lesson(lesson_nb)
data_array.shuffle() data_array.shuffle()
words_to_present.clear() words_to_present.clear()
words_to_present_next.clear() words_to_present_next.clear()
@@ -98,7 +98,7 @@ func _present_next_word() -> void:
label.show() label.show()
label.text = words_to_present[0] label.text = words_to_present[0]
if tutorial_count == 0: if tutorial_count == 0:
var speech: = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name] as String, "intro_test_game_first_word")) var speech: AudioStreamMP3 = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name] as String, "intro_test_game_first_word"))
minigame_ui.play_kalulu_speech(speech) minigame_ui.play_kalulu_speech(speech)
await minigame_ui.kalulu_speech_ended await minigame_ui.kalulu_speech_ended
@@ -127,8 +127,8 @@ func _beacon2_drop_data(_at_position: Vector2, _data: Variant) -> void:
func _on_beacon_fish_dropped(is_answered_real: bool) -> void: func _on_beacon_fish_dropped(is_answered_real: bool) -> void:
var is_really_real: = words_to_present[0] in stimuli var is_really_real: bool = words_to_present[0] in stimuli
var is_correct: = is_answered_real == is_really_real var is_correct: bool = is_answered_real == is_really_real
if is_correct: if is_correct:
if is_answered_real: if is_answered_real:
real_right_fx.play() real_right_fx.play()
@@ -136,12 +136,12 @@ func _on_beacon_fish_dropped(is_answered_real: bool) -> void:
false_right_fx.play() false_right_fx.play()
words_to_present.pop_front() words_to_present.pop_front()
if tutorial_count == 0: if tutorial_count == 0:
var speech: = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name] as String, "win_test_game_first_word")) var speech: AudioStreamMP3 = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name] as String, "win_test_game_first_word"))
minigame_ui.play_kalulu_speech(speech) minigame_ui.play_kalulu_speech(speech)
await minigame_ui.kalulu_speech_ended await minigame_ui.kalulu_speech_ended
tutorial_count += 1 tutorial_count += 1
elif tutorial_count == 1: elif tutorial_count == 1:
var speech: = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name] as String, "win_test_game_second_word")) var speech: AudioStreamMP3 = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name] as String, "win_test_game_second_word"))
minigame_ui.play_kalulu_speech(speech) minigame_ui.play_kalulu_speech(speech)
await minigame_ui.kalulu_speech_ended await minigame_ui.kalulu_speech_ended
tutorial_count += 1 tutorial_count += 1
@@ -152,12 +152,12 @@ func _on_beacon_fish_dropped(is_answered_real: bool) -> void:
false_wrong_fx.play() false_wrong_fx.play()
words_to_present_next.append(words_to_present.pop_front()) words_to_present_next.append(words_to_present.pop_front())
if tutorial_count == 0: if tutorial_count == 0:
var speech: = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name] as String, "lose_test_game_first_word")) var speech: AudioStreamMP3 = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name] as String, "lose_test_game_first_word"))
minigame_ui.play_kalulu_speech(speech) minigame_ui.play_kalulu_speech(speech)
await minigame_ui.kalulu_speech_ended await minigame_ui.kalulu_speech_ended
tutorial_count += 1 tutorial_count += 1
elif tutorial_count == 1: elif tutorial_count == 1:
var speech: = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name] as String, "lose_test_game_second_word")) var speech: AudioStreamMP3 = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name] as String, "lose_test_game_second_word"))
minigame_ui.play_kalulu_speech(speech) minigame_ui.play_kalulu_speech(speech)
await minigame_ui.kalulu_speech_ended await minigame_ui.kalulu_speech_ended
tutorial_count += 1 tutorial_count += 1
@@ -73,9 +73,9 @@ func _spawn() -> void:
var left_border: = 0. var left_border: = 0.
# Blocking jellyfish is supposed to be ordered # Blocking jellyfish is supposed to be ordered
for blocking in blocking_jellyfish: for blocking in blocking_jellyfish:
permitted_range += max(0, blocking.position.x - left_border - jellyfish_width) permitted_range += maxf(0.0, blocking.position.x - left_border - jellyfish_width)
left_border = blocking.position.x + blocking.size.x left_border = blocking.position.x + blocking.size.x
permitted_range += max(0, spawning_space.size.x - left_border) permitted_range += maxf(0.0, spawning_space.size.x - left_border)
if permitted_range <= 0: if permitted_range <= 0:
new_jellyfish.queue_free() new_jellyfish.queue_free()
return return
@@ -95,7 +95,7 @@ func _spawn() -> void:
left_border = 0 left_border = 0
# Blocking jellyfish is supposed to be ordered # Blocking jellyfish is supposed to be ordered
for blocking in blocking_jellyfish: for blocking in blocking_jellyfish:
var local_permitted_range: float = max(0, blocking.position.x - left_border - jellyfish_width) var local_permitted_range: float = maxf(0.0, blocking.position.x - left_border - jellyfish_width)
if local_permitted_range <= random_spawn: if local_permitted_range <= random_spawn:
random_spawn -= local_permitted_range random_spawn -= local_permitted_range
else: else:
@@ -6,7 +6,7 @@ const PenguinLabel: = preload("res://sources/minigames/penguin/penguin_label.gd"
const label_scene: PackedScene = preload("res://sources/minigames/penguin/penguin_label.tscn") const label_scene: PackedScene = preload("res://sources/minigames/penguin/penguin_label.tscn")
const silent_phoneme: = "#" const silent_phoneme: String = "#"
@onready var penguin: Penguin = $GameRoot/Penguin @onready var penguin: Penguin = $GameRoot/Penguin
@@ -23,8 +23,8 @@ func _find_stimuli_and_distractions() -> void:
if sentences_list.is_empty(): if sentences_list.is_empty():
return return
var current_lesson_sentences: = [] var current_lesson_sentences: Array[Dictionary]
var previous_lesson_sentences: = [] var previous_lesson_sentences: Array[Dictionary]
for sentence: Dictionary in sentences_list: for sentence: Dictionary in sentences_list:
if sentence.LessonNb == lesson_nb: if sentence.LessonNb == lesson_nb:
@@ -75,7 +75,7 @@ func _find_stimuli_and_distractions() -> void:
for sentence: Dictionary in stimuli: for sentence: Dictionary in stimuli:
sentence.GPs = Database.get_GPs_from_sentence(sentence.ID as int) sentence.GPs = Database.get_GPs_from_sentence(sentence.ID as int)
Logger.debug("PenguinMinigame: %s" % stimuli) Logger.debug("PenguinMinigame: Stimuli: %s" % str(stimuli))
# Launch the minigame # Launch the minigame
@@ -95,7 +95,7 @@ func _setup_word_progression() -> void:
node.queue_free() node.queue_free()
labels.clear() labels.clear()
var stimulus: = _get_current_stimulus() var stimulus: Dictionary = _get_current_stimulus()
var first_GP: bool = true var first_GP: bool = true
var last_wordID: int var last_wordID: int
+3 -3
View File
@@ -3,12 +3,12 @@ class_name Coroutine
# For resume functionality # For resume functionality
signal resume_signal() signal resume_signal()
var _is_started: = false var _is_started: bool = false
var is_completed: = false var is_completed: bool = false
# For join functionality # For join functionality
signal _join() signal _join()
var _ended_count: = -1 var _ended_count: int = -1
var return_value: Array var return_value: Array
+1 -1
View File
@@ -433,7 +433,7 @@ func get_min_lesson_for_word_id(word_id: int) -> int:
if index < 0: if index < 0:
minimum = -1 minimum = -1
break break
minimum = max(minimum, index) minimum = maxi(minimum, index)
return minimum return minimum
+5 -3
View File
@@ -26,7 +26,7 @@ func set_environment(env: int) -> void:
func submit_student_metrics(level: int, elapsed_time: int) -> void: func submit_student_metrics(level: int, elapsed_time: int) -> void:
await _post_request("submit-student-metrics", {"student_id": 3, "level": level, "time_spent": elapsed_time}) await _post_request("submit_student_metrics", {"student_id": UserDataManager.student, "level": level, "time_spent": elapsed_time})
# Response from the last request # Response from the last request
@@ -136,8 +136,10 @@ func _get_request(URI: String, params: Dictionary) -> void:
func _post_request(URI: String, params: Dictionary) -> void: func _post_request(URI: String, params: Dictionary) -> void:
code = 0 code = 0
json = {} json = {}
Logger.debug("ServerManager Sending POST request. URI = %s. Parameters = %s " % [URI, params]) var url: String = _create_URI_with_parameters(environment_url + URI, params)
if http_request.request(_create_URI_with_parameters(environment_url + URI, params), _create_request_headers(), HTTPClient.METHOD_POST, "") == 0: var headers: PackedStringArray = _create_request_headers()
Logger.debug("ServerManager Sending POST request. URL = %s.\nHeaders = %s " % [url, str(headers)])
if http_request.request(url, headers, HTTPClient.METHOD_POST, "") == 0:
await request_completed await request_completed
else: else:
Logger.error("ServerManager Error sending POST request") Logger.error("ServerManager Error sending POST request")
+6 -6
View File
@@ -21,10 +21,10 @@ func get_value() -> Variant:
elif control is TextEdit: elif control is TextEdit:
return (control as TextEdit).text return (control as TextEdit).text
elif control is ItemList: elif control is ItemList:
var selected_indexes: PackedInt32Array = control.get_selected_items() var selected_indexes: PackedInt32Array = (control as ItemList).get_selected_items()
if not selected_indexes or selected_indexes.size() == 0: if not selected_indexes or selected_indexes.size() == 0:
return null return null
if control.select_mode == ItemList.SELECT_SINGLE: if (control as ItemList).select_mode == ItemList.SELECT_SINGLE:
return selected_indexes[0] return selected_indexes[0]
return selected_indexes return selected_indexes
@@ -37,11 +37,11 @@ func set_value(value: Variant) -> void:
if control is Range: if control is Range:
if value is float: if value is float:
control.value = value (control as Range).value = value
elif value is int: elif value is int:
control.value = float(value) (control as Range).value = float(value as int)
elif control is LineEdit or control is TextEdit: elif control is LineEdit or control is TextEdit:
control.text = str(value) (control as LineEdit).text = str(value)
elif control is ItemList: elif control is ItemList:
if value is int: if value is int:
control.select(value, true) (control as ItemList).select(value as int, true)
+5 -6
View File
@@ -3,18 +3,17 @@ extends Node
signal finished() signal finished()
const Rocket: = preload("res://sources/utils/fx/rocket.gd") const Rocket: = preload("res://sources/utils/fx/rocket.gd")
const rocket_scene: = preload("res://sources/utils/fx/rocket.tscn") const rocket_scene: PackedScene = preload("res://sources/utils/fx/rocket.tscn")
@export var number_of_rockets: = 25 @export var number_of_rockets: int = 25
@onready var fire_delay_timer: Timer = $FireDelayTimer @onready var fire_delay_timer: Timer = $FireDelayTimer
@onready var starts: = $Starts.get_children() @onready var starts: Array[Node] = $Starts.get_children()
@onready var ends: = $Ends.get_children() @onready var ends: Array[Node] = $Ends.get_children()
@onready var rockets: Node2D = $Rockets @onready var rockets: Node2D = $Rockets
var count: int = 0
var count: = 0
func start() -> void: func start() -> void:
+13 -13
View File
@@ -1,7 +1,7 @@
extends Path2D extends Path2D
@export var spread_angle := PI/8.0 @export var spread_angle: float = PI/8.0
@export var segments := 5 @export var segments: int = 5
@onready var path_follow: PathFollow2D = $PathFollow2D @onready var path_follow: PathFollow2D = $PathFollow2D
@@ -14,7 +14,7 @@ extends Path2D
@onready var firework_audio_player: AudioStreamPlayer2D = $FireworkAudioPlayer @onready var firework_audio_player: AudioStreamPlayer2D = $FireworkAudioPlayer
@onready var blast_audio_player: AudioStreamPlayer2D = $BlastAudioPlayer @onready var blast_audio_player: AudioStreamPlayer2D = $BlastAudioPlayer
const firework_sounds: = [ const firework_sounds: Array[AudioStreamMP3] = [
preload("res://assets/sfx/fireworks_1.mp3"), preload("res://assets/sfx/fireworks_1.mp3"),
preload("res://assets/sfx/fireworks_2.mp3"), preload("res://assets/sfx/fireworks_2.mp3"),
preload("res://assets/sfx/fireworks_3.mp3"), preload("res://assets/sfx/fireworks_3.mp3"),
@@ -22,7 +22,7 @@ const firework_sounds: = [
preload("res://assets/sfx/fireworks_5.mp3"), preload("res://assets/sfx/fireworks_5.mp3"),
] ]
const blast_sounds: = [ const blast_sounds: Array[AudioStreamMP3] = [
preload("res://assets/sfx/blast_1.mp3"), preload("res://assets/sfx/blast_1.mp3"),
preload("res://assets/sfx/blast_2.mp3"), preload("res://assets/sfx/blast_2.mp3"),
preload("res://assets/sfx/blast_3.mp3"), preload("res://assets/sfx/blast_3.mp3"),
@@ -30,7 +30,7 @@ const blast_sounds: = [
preload("res://assets/sfx/blast_5.mp3"), preload("res://assets/sfx/blast_5.mp3"),
] ]
const colors: = [ const colors: Array[Color] = [
Color(0.427, 0.796, 1), Color(0.427, 0.796, 1),
Color(0.976, 0.322, 0.392), Color(0.976, 0.322, 0.392),
Color(1, 0.396, 0.753), Color(1, 0.396, 0.753),
@@ -40,7 +40,7 @@ const colors: = [
Color(0.216, 0.757, 0.341), Color(0.216, 0.757, 0.341),
] ]
var ind_color: = 0 var ind_color: int = 0
func _ready() -> void: func _ready() -> void:
@@ -56,12 +56,12 @@ func start(start_point: Vector2, end_point: Vector2) -> void:
create_path(start_point, end_point) create_path(start_point, end_point)
var travel_time: = randf_range(0.5, 1.0) var travel_time: float = randf_range(0.5, 1.0)
traveling_timer.start(travel_time) traveling_timer.start(travel_time)
path_follow.progress_ratio = 0.0 path_follow.progress_ratio = 0.0
var tween: = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_CIRC) var tween: Tween = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_CIRC)
var _a: = tween.tween_property(path_follow, "progress_ratio", 1.0, travel_time) var _a: PropertyTweener = tween.tween_property(path_follow, "progress_ratio", 1.0, travel_time)
firework_audio_player.play() firework_audio_player.play()
@@ -73,10 +73,10 @@ func create_path(start_point: Vector2, end_point: Vector2) -> void:
var general_direction: = (end_point - start_point).normalized() var general_direction: = (end_point - start_point).normalized()
curve.add_point(start_point, -segment_length * general_direction / 2.0, segment_length * general_direction / 2.0) curve.add_point(start_point, -segment_length * general_direction / 2.0, segment_length * general_direction / 2.0)
for _segment in range(segments): for _segment: int in range(segments):
var angle := randf_range(-spread_angle / 2, spread_angle / 2) var angle: float = randf_range(-spread_angle / 2, spread_angle / 2)
var new := current + (current.direction_to(end_point) * segment_length).rotated(angle) var new: Vector2 = current + (current.direction_to(end_point) * segment_length).rotated(angle)
var direction: = (new - current).normalized() var direction: Vector2 = (new - current).normalized()
curve.add_point(new, -segment_length * direction / 2.0, segment_length * direction / 2.0) curve.add_point(new, -segment_length * direction / 2.0, segment_length * direction / 2.0)
current = new current = new
+1 -1
View File
@@ -13,4 +13,4 @@ func _process(_delta: float) -> void:
if OS.get_name() == "Android": if OS.get_name() == "Android":
@warning_ignore("narrowing_conversion") @warning_ignore("narrowing_conversion")
margin *= screen_scale margin *= screen_scale
self["theme_override_constants/margin_bottom"] = max(floori(margin), 0) self["theme_override_constants/margin_bottom"] = maxi(floori(margin), 0)
+13 -16
View File
@@ -3,24 +3,24 @@ class_name Bezier
static func bezier_square_error(current_points: Array, ref_points: Array) -> float: static func bezier_square_error(current_points: Array, ref_points: Array) -> float:
var samples: = bezier_sampling(current_points, 25) var samples: Array[Vector2] = bezier_sampling(current_points, 25)
var curve: = Curve2D.new() var curve: Curve2D = Curve2D.new()
for point: Vector2 in samples: for point: Vector2 in samples:
curve.add_point(point) curve.add_point(point)
var error: = 0.0 var error: float = 0.0
for point: Vector2 in ref_points: for point: Vector2 in ref_points:
var curve_point: = curve.get_closest_point(point) var curve_point: Vector2 = curve.get_closest_point(point)
error += pow(curve_point.distance_to(point), 2.0) error += pow(curve_point.distance_to(point), 2.0)
return error return error
static func bezier_sampling(points: Array, number_of_samples: int) -> Array: static func bezier_sampling(points: Array, number_of_samples: int) -> Array[Vector2]:
var sample_points: = [] var sample_points: Array[Vector2]
for index: int in range(number_of_samples + 1): for index: int in range(number_of_samples + 1):
var sample: = bezier(float(index) / float(number_of_samples), points) var sample: Vector2 = bezier(float(index) / float(number_of_samples), points)
sample_points.append(sample) sample_points.append(sample)
return sample_points return sample_points
@@ -30,14 +30,14 @@ static func bezier(t: float, points: Array) -> Vector2:
var n: int = points.size() - 1 var n: int = points.size() - 1
var r: Vector2 = Vector2.ZERO var r: Vector2 = Vector2.ZERO
for index: int in range(n + 1): for index: int in range(n + 1):
var bern: = bernstein(t, n, index) var bern: float = bernstein(t, n, index)
r += bern * points[index] r += bern * points[index]
return r return r
static func bernstein(t: float, m: int, i: int) -> float: static func bernstein(t: float, m: int, i: int) -> float:
var b_i_m: = float(binomial(i, m)) var b_i_m: float = float(binomial(i, m))
var t_i: float = pow(t, i) var t_i: float = pow(t, i)
var t_m_i: float = pow(1.0 - t, m - i) var t_m_i: float = pow(1.0 - t, m - i)
var result: float = b_i_m * t_i * t_m_i var result: float = b_i_m * t_i * t_m_i
@@ -46,13 +46,10 @@ static func bernstein(t: float, m: int, i: int) -> float:
static func binomial(k: int, n: int) -> int: static func binomial(k: int, n: int) -> int:
var n_f: = factorial(n) var n_f: int = factorial(n)
var k_f: = factorial(k) var k_f: int = factorial(k)
var n_k_f: = factorial(n - k) var n_k_f: int = factorial(n - k)
return int(float(n_f) / (float(k_f) * float(n_k_f)))
var r: = int(float(n_f) / (float(k_f) * float(n_k_f)))
return r
static func factorial(k: int) -> int: static func factorial(k: int) -> int:
+2 -2
View File
@@ -29,8 +29,8 @@ func _get_minimum_size() -> Vector2:
var min_size: = Vector2(0, 0) var min_size: = Vector2(0, 0)
for c: Control in get_children(): for c: Control in get_children():
var c_min_size: = c.get_combined_minimum_size() var c_min_size: = c.get_combined_minimum_size()
min_size.x = max(c_min_size.x, min_size.x) min_size.x = maxf(c_min_size.x, min_size.x)
min_size.y = max(c_min_size.y, min_size.y) min_size.y = maxf(c_min_size.y, min_size.y)
return min_size return min_size
+2 -2
View File
@@ -7,7 +7,7 @@ class_name SpriteControl
func set_sprites(p_sprites: Array[CanvasItem]) -> void: func set_sprites(p_sprites: Array[CanvasItem]) -> void:
for p_sprite in p_sprites: for p_sprite: CanvasItem in p_sprites:
if p_sprite: if p_sprite:
if p_sprite is Sprite2D: if p_sprite is Sprite2D:
var p_sprite_2D: Sprite2D = p_sprite var p_sprite_2D: Sprite2D = p_sprite
@@ -28,7 +28,7 @@ func _on_resized() -> void:
func _resize_sprites() -> void: func _resize_sprites() -> void:
for sprite in sprites: for sprite: CanvasItem in sprites:
if sprite is Sprite2D: if sprite is Sprite2D:
var sprite_2D: Sprite2D = sprite var sprite_2D: Sprite2D = sprite
if sprite_2D.texture: if sprite_2D.texture: