Clean and hard-typing
This commit is contained in:
+3
-3
@@ -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
@@ -1,4 +1,4 @@
|
|||||||
extends Resource
|
extends Resource
|
||||||
class_name ProfToolSave
|
class_name ProfToolSave
|
||||||
|
|
||||||
@export var selected_language: = ""
|
@export var selected_language: String = ""
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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():
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|
||||||
|
|||||||
@@ -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])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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,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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user