Adult check for boss defeat

This commit is contained in:
Adrien Ufferte
2026-01-19 10:21:34 +01:00
parent 0aa2983de6
commit fc3589da80
9 changed files with 199 additions and 2 deletions
+1
View File
@@ -17,6 +17,7 @@ DEVICE_NUMBER,Appareil {number},Dispositivo {number},Dispositivo {number}
SETTINGS,Paramètres,Configuración,Parâmetros
ADULT_CHECK_PROMPT,"Veuillez confirmer que vous êtes un adulte !
Appuyez sur les touches {1}, {2} et {3}","Confirme que es un adulto! Seleccione {1}, {2} y {3}","Por favor, confirme que você é um adulto! Pressione as teclas {1}, {2} e {3}"
ADULT_BOSS_BLOCK_PROMPT,"Un adulte doit intervenir. Refaites le boss avec l'enfant et demandez-lui de prononcer les mots à voix haute pour vérifier qu'il sait bien lire. Si l'enfant échoue à lire correctement les mots, il est recommandé de revenir en arrière dans les niveaux pour reprendre les bases. Pour débloquer l'application, appuyez sur les touches {1}, {2} et {3}","Se necesita la intervención de un adulto. Rehaga el jefe con el niño y pídale que pronuncie las palabras en voz alta para comprobar que sabe leer. Si el niño no logra leer correctamente las palabras, se recomienda volver atrás en los niveles para repasar las bases. Para desbloquear la aplicación, presione las teclas {1}, {2} y {3}","É necessária a intervenção de um adulto. Refaça o chefe com a criança e peça que ela pronuncie as palavras em voz alta para verificar se sabe ler. Se a criança não conseguir ler corretamente as palavras, recomenda-se voltar nos níveis para reforçar as bases. Para desbloquear o aplicativo, pressione as teclas {1}, {2} e {3}"
STAR,Étoile,Estrella,Estrela
BAR,Barre,Barra,Barra
CIRCLE,Cercle,Círculo,Círculo
1 keys fr es pt_BR
17 SETTINGS Paramètres Configuración Parâmetros
18 ADULT_CHECK_PROMPT Veuillez confirmer que vous êtes un adulte ! Appuyez sur les touches {1}, {2} et {3} Confirme que es un adulto! Seleccione {1}, {2} y {3} Por favor, confirme que você é um adulto! Pressione as teclas {1}, {2} e {3}
19 STAR ADULT_BOSS_BLOCK_PROMPT Étoile Un adulte doit intervenir. Refaites le boss avec l'enfant et demandez-lui de prononcer les mots à voix haute pour vérifier qu'il sait bien lire. Si l'enfant échoue à lire correctement les mots, il est recommandé de revenir en arrière dans les niveaux pour reprendre les bases. Pour débloquer l'application, appuyez sur les touches {1}, {2} et {3} Estrella Se necesita la intervención de un adulto. Rehaga el jefe con el niño y pídale que pronuncie las palabras en voz alta para comprobar que sabe leer. Si el niño no logra leer correctamente las palabras, se recomienda volver atrás en los niveles para repasar las bases. Para desbloquear la aplicación, presione las teclas {1}, {2} y {3} Estrela É necessária a intervenção de um adulto. Refaça o chefe com a criança e peça que ela pronuncie as palavras em voz alta para verificar se sabe ler. Se a criança não conseguir ler corretamente as palavras, recomenda-se voltar nos níveis para reforçar as bases. Para desbloquear o aplicativo, pressione as teclas {1}, {2} e {3}
20 STAR Étoile Estrella Estrela
21 BAR Barre Barra Barra
22 CIRCLE Cercle Círculo Círculo
23 PLUS Plus Más Mais
+32
View File
@@ -19,6 +19,8 @@ static var cached_boss_gate_lessons_total: int = -1
@export var highest_boss_defeated: int = 0:
set(value):
highest_boss_defeated = _sanitize_highest_boss(value)
@export var boss_failure_streak: int = 0
@export var boss_blocked: bool = false
@export var last_modified: String
@@ -279,11 +281,41 @@ func boss_completed(lesson_number: int) -> bool:
if lesson_number <= highest_boss_defeated:
return false
highest_boss_defeated = lesson_number
if boss_failure_streak != 0:
boss_failure_streak = 0
last_modified = Time.get_datetime_string_from_system(true)
progression_changed.emit()
return true
func register_boss_failure() -> bool:
if boss_blocked:
return true
boss_failure_streak = max(0, boss_failure_streak) + 1
if boss_failure_streak >= 2:
boss_blocked = true
last_modified = Time.get_datetime_string_from_system(true)
progression_changed.emit()
return boss_blocked
func reset_boss_failure_streak() -> void:
if boss_failure_streak == 0:
return
boss_failure_streak = 0
last_modified = Time.get_datetime_string_from_system(true)
progression_changed.emit()
func clear_boss_block() -> void:
if not boss_blocked and boss_failure_streak == 0:
return
boss_blocked = false
boss_failure_streak = 0
last_modified = Time.get_datetime_string_from_system(true)
progression_changed.emit()
func add_level_time(lesson_number: int, game_number: int, time_spent: int) -> void:
Log.trace("StudentProgression: Add time to level %d, minigame %d. Time added: %s" % [lesson_number, game_number, time_spent])
if game_number > 2:
-1
View File
@@ -361,7 +361,6 @@ func _ready() -> void:
Log.error("Gardens: Ready: No data for student progression")
await OpeningCurtain.open()
return
await get_tree().process_frame
_lock()
@@ -0,0 +1,56 @@
extends Control
signal unlocked()
const SYMBOLS_NAMES: Dictionary[String, String] = {
"1": "STAR",
"2": "BAR",
"3": "CIRCLE",
"4": "PLUS",
"5": "SQUARE",
"6": "TRIANGLE",
}
var password: String = ""
@onready var code_keyboard: CodeKeyboard = %CodeKeyboard
@onready var password_label: Label = %PasswordLabel
func _ready() -> void:
process_mode = Node.PROCESS_MODE_ALWAYS
hide()
_reset_password()
func _reset_password() -> void:
password = str(TeacherSettings.AVAILABLE_CODES.pick_random())
var password_array: PackedStringArray = password.split("")
password_label.text = tr("ADULT_BOSS_BLOCK_PROMPT").format(
{
"1": tr(SYMBOLS_NAMES[password_array[0]]),
"2": tr(SYMBOLS_NAMES[password_array[1]]),
"3": tr(SYMBOLS_NAMES[password_array[2]])
}
)
func _on_code_keyboard_password_entered(entered_password: String) -> void:
if password != entered_password:
code_keyboard.reset_password()
_reset_password()
return
if UserDataManager.student_progression:
UserDataManager.student_progression.clear_boss_block()
get_tree().paused = false
hide()
unlocked.emit()
func show_block() -> void:
get_tree().paused = true
code_keyboard.reset_password()
_reset_password()
show()
@@ -0,0 +1 @@
uid://dxs13x1x36ukn
@@ -0,0 +1,80 @@
[gd_scene load_steps=5 format=3 uid="uid://b7rx6esglyd6c"]
[ext_resource type="PackedScene" uid="uid://djduptonofbh4" path="res://sources/menus/components/code_keyboard.tscn" id="1_6q05s"]
[ext_resource type="Script" uid="uid://dxs13x1x36ukn" path="res://sources/menus/adult_block/adult_boss_block.gd" id="1_jf7p7"]
[ext_resource type="PackedScene" uid="uid://wdjp1sv55q4f" path="res://sources/menus/components/night_sky/night_sky.tscn" id="2_cdfx1"]
[ext_resource type="PackedScene" uid="uid://dxc82xcl7jncd" path="res://sources/menus/main/plants/palm.tscn" id="3_0u8tq"]
[node name="AdultBossBlock" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_jf7p7")
[node name="Background" parent="." instance=ExtResource("2_cdfx1")]
layout_mode = 1
[node name="Palm" parent="Background" instance=ExtResource("3_0u8tq")]
position = Vector2(1280, 1792)
scale = Vector2(2.5, 2.5)
[node name="PanelContainer" type="PanelContainer" parent="."]
layout_mode = 1
anchors_preset = -1
anchor_left = 0.156
anchor_top = 0.06
anchor_right = 0.84375
anchor_bottom = 0.39
grow_horizontal = 2
grow_vertical = 2
theme_type_variation = &"PanelKalulu"
[node name="LabelContainer" type="MarginContainer" parent="PanelContainer"]
layout_mode = 2
theme_override_constants/margin_left = 30
theme_override_constants/margin_top = 20
theme_override_constants/margin_right = 30
theme_override_constants/margin_bottom = 20
[node name="PasswordLabel" type="Label" parent="PanelContainer/LabelContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(1500, 600)
layout_mode = 2
size_flags_vertical = 1
theme_override_font_sizes/font_size = 60
text = "ADULT_BOSS_BLOCK_PROMPT"
autowrap_mode = 2
[node name="CodeKeyboard" parent="." instance=ExtResource("1_6q05s")]
unique_name_in_owner = true
layout_mode = 0
anchors_preset = 0
anchor_right = 0.0
anchor_bottom = 0.0
offset_right = 2560.0
offset_bottom = 1800.0
grow_horizontal = 1
grow_vertical = 0
[node name="PasswordVisualizer" parent="CodeKeyboard" index="0"]
offset_left = -376.0
offset_top = -164.0
offset_right = 376.0
offset_bottom = 56.0
key_size = 200
[node name="Icon1" parent="CodeKeyboard/PasswordVisualizer/Panel1" index="0"]
custom_minimum_size = Vector2(200, 200)
[node name="Icon2" parent="CodeKeyboard/PasswordVisualizer/Panel2" index="0"]
custom_minimum_size = Vector2(200, 200)
[node name="Icon3" parent="CodeKeyboard/PasswordVisualizer/Panel3" index="0"]
custom_minimum_size = Vector2(200, 200)
[connection signal="password_entered" from="CodeKeyboard" to="." method="_on_code_keyboard_password_entered"]
[editable path="CodeKeyboard"]
+10
View File
@@ -211,6 +211,8 @@ func _win() -> void:
if gardens_data.has("boss_gate_lesson"):
gardens_data.boss_completed = UserDataManager.student_progression.boss_completed(gardens_data.boss_gate_lesson as int)
gardens_data.first_clear = gardens_data.boss_completed
if not is_final_boss:
UserDataManager.student_progression.reset_boss_failure_streak()
else:
gardens_data.first_clear = UserDataManager.student_progression.game_completed(lesson_nb, minigame_number)
@@ -272,6 +274,14 @@ func _lose() -> void:
minigame_ui.play_kalulu_speech(lose_kalulu_speech)
await minigame_ui.kalulu_speech_ended
if gardens_data.has("boss_gate_lesson") and not is_final_boss and UserDataManager.student_progression:
var is_blocked: bool = UserDataManager.student_progression.register_boss_failure()
if is_blocked:
if has_method("show_adult_block"):
call("show_adult_block")
else:
Log.error("BaseMinigame: Adult block requested but no handler exists for %s" % Type.keys()[minigame_name])
return
_reset()
+12
View File
@@ -31,6 +31,7 @@ var tutorial_count: int = 0
@onready var progress_gauge: PercentMarginContainer = %ProgressionGaugePercentMarginContainer
@onready var progress_gauge_goal: PercentMarginContainer = %ProgressionGaugeGoalPercentMarginContainer2
@onready var progress_gauge_internal: NinePatchRect = %ProgressionGaugeInternal
@onready var adult_block: Control = %AdultBossBlock
func _fish_get_drag_data(_at_position: Vector2) -> Variant:
@@ -42,6 +43,8 @@ func _fish_get_drag_data(_at_position: Vector2) -> Variant:
func _ready() -> void:
super()
if adult_block and adult_block.has_signal("unlocked"):
adult_block.unlocked.connect(_on_adult_block_unlocked)
fish_start_zone.set_drag_forwarding(_fish_get_drag_data, Callable(), Callable())
(beacon1 as Control).set_drag_forwarding(Callable(), _beacon_can_drop_data, _beacon1_drop_data)
(beacon2 as Control).set_drag_forwarding(Callable(), _beacon_can_drop_data, _beacon2_drop_data)
@@ -201,3 +204,12 @@ func _ensure_words_to_present_count(target_count: int) -> void:
words_to_present.append_array(base_pool)
if words_to_present.size() > target_count:
words_to_present.resize(target_count)
func show_adult_block() -> void:
if adult_block and adult_block.has_method("show_block"):
adult_block.call("show_block")
func _on_adult_block_unlocked() -> void:
await _reset()
+7 -1
View File
@@ -1,4 +1,4 @@
[gd_scene load_steps=70 format=3 uid="uid://df5derhil64ca"]
[gd_scene load_steps=71 format=3 uid="uid://df5derhil64ca"]
[ext_resource type="PackedScene" uid="uid://8awe4usnucyv" path="res://sources/minigames/base/base_minigame.tscn" id="1_itrpi"]
[ext_resource type="Script" uid="uid://dgodk76761a1n" path="res://sources/minigames/fish/fish_minigame.gd" id="2_68jip"]
@@ -17,6 +17,7 @@
[ext_resource type="Texture2D" uid="uid://disgg14rdmp81" path="res://assets/minigames/fish/textplank.png" id="13_3p0ue"]
[ext_resource type="Script" uid="uid://d5qkkg88431w" path="res://sources/utils/percent_margin_container.gd" id="14_b3ilp"]
[ext_resource type="LabelSettings" uid="uid://bguqnhiblwick" path="res://resources/themes/minigames_label_settings.tres" id="17_47luc"]
[ext_resource type="PackedScene" uid="uid://b7rx6esglyd6c" path="res://sources/menus/adult_block/adult_boss_block.tscn" id="18_4v0wd"]
[sub_resource type="Environment" id="Environment_5bcb7"]
background_mode = 3
@@ -724,5 +725,10 @@ text = "a"
label_settings = ExtResource("17_47luc")
horizontal_alignment = 1
[node name="AdultBossBlock" parent="." index="5" instance=ExtResource("18_4v0wd")]
unique_name_in_owner = true
visible = false
layout_mode = 1
[connection signal="beacon_fish_dropped" from="." to="." method="_on_beacon_fish_dropped"]
[connection signal="animation_finished" from="GameRoot/AspectRatioContainer/Fish/FishAnimatedSprite" to="." method="_on_fish_animated_sprite_animation_finished"]