Enrichit les declencheurs/actions de scene (clic/survol/affichage, surbrillance/video/son/visibilite/indication/attendre) et fiabilise la pose d'un fond/decor importe
- Ajoute clic/survol/affichage-ecran comme declencheurs, et surbrillance, video, son, visibilite, indication, attendre comme actions, utilisables aussi bien par l'editeur manuel (menu lateral Objets/Ecran) que par Ruby (IA), avec blocs deplacables/supprimables dans une chaine. - Corrige plusieurs variantes du bug "impossible de poser un objet hors du champ de la camera" (troncature du chainage d'actions a 4 maillons, fond importe pose a 128x128 au lieu de sa taille reelle, decalage du fond au vrai glisser-depose, redimensionnement manuel jamais propage au monde). - Ajoute un vrai glisser-depose depuis la galerie vers la scene, la gestion complete de "Mes assets" (sous-sections Fonds/Decors/Sons/ Videos, suppression, reclassement fond<->decor sans re-upload). - Ajoute l'upload de son (limite 3 min) et de video (MP4 uniquement, limite 5 min), avec validation de la duree reelle du fichier, et une replique audio optionnelle dans une bulle de dialogue. - Fixe la taille de pose d'un objet/decor importe a 200x200 avec une boite de collision de 150x150. - Filtre le selecteur de fichier des actions son/video par type reel. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
b07b231a61
commit
559331f9cf
@@ -200,6 +200,92 @@ def test_dispatch_append_action_to_trigger_extends_an_existing_chain(client, tmp
|
||||
assert screens.resolve_collision_rules(obj)[0]["action"]["then"]["target_variable"] == "score_ia"
|
||||
|
||||
|
||||
def test_dispatch_set_collision_rules_accepts_clic_and_survol_triggers(client, tmp_game_slug_cleanup):
|
||||
slug, screen_id = _create_jeu2d_game(client, tmp_game_slug_cleanup)
|
||||
object_id = screens.add_scene_object(slug, screen_id, kind="decor")
|
||||
rules = [{"trigger": "clic", "action": {"type": "surbrillance", "object_id": object_id, "valeur": "toggle"}}]
|
||||
dispatch_tool(slug, screen_id, 1, "set_collision_rules", {"object_id": object_id, "rules": rules})
|
||||
obj = screens.get_scene_object(slug, object_id)
|
||||
assert screens.resolve_collision_rules(obj) == rules
|
||||
|
||||
|
||||
def test_dispatch_set_screen_triggers_sanitizes_and_stores(client, tmp_game_slug_cleanup):
|
||||
slug, screen_id = _create_jeu2d_game(client, tmp_game_slug_cleanup)
|
||||
rules = [{"trigger": "affichage", "action": {"type": "video", "asset_url": "/assets/1/intro.mp4", "mode": "plein_ecran"}}]
|
||||
result = dispatch_tool(slug, screen_id, 1, "set_screen_triggers", {"rules": rules})
|
||||
assert result["ok"] is True
|
||||
screen = screens.get_screen(slug, screen_id)
|
||||
assert screens.resolve_screen_triggers(screen) == rules
|
||||
|
||||
|
||||
def test_dispatch_append_action_to_screen_trigger_extends_an_existing_chain(client, tmp_game_slug_cleanup):
|
||||
slug, screen_id = _create_jeu2d_game(client, tmp_game_slug_cleanup)
|
||||
screens.set_screen_triggers(slug, screen_id, screens.sanitize_screen_triggers([
|
||||
{"trigger": "affichage", "action": {"type": "dialogue", "dialogue": {"id": "d_1", "lines": []}}},
|
||||
]))
|
||||
result = dispatch_tool(slug, screen_id, 1, "append_action_to_screen_trigger", {
|
||||
"after_id": "d_1",
|
||||
"action": {"type": "variable", "target_variable": "score_ia", "data_operation": "incrementer", "data_value": "1"},
|
||||
})
|
||||
assert result["ok"] is True
|
||||
screen = screens.get_screen(slug, screen_id)
|
||||
assert screens.resolve_screen_triggers(screen)[0]["action"]["then"]["target_variable"] == "score_ia"
|
||||
|
||||
|
||||
def test_dispatch_remove_trigger_action_removes_a_leaf(client, tmp_game_slug_cleanup):
|
||||
slug, screen_id = _create_jeu2d_game(client, tmp_game_slug_cleanup)
|
||||
object_id = screens.add_scene_object(slug, screen_id, kind="decor")
|
||||
screens.set_scene_object_collision_rules(slug, object_id, screens.sanitize_collision_rules([
|
||||
{"trigger": "collision", "action": {"type": "dialogue", "dialogue": {"id": "d_1", "lines": []}}},
|
||||
]))
|
||||
result = dispatch_tool(slug, screen_id, 1, "remove_trigger_action", {"object_id": object_id, "leaf_id": "d_1"})
|
||||
assert result["ok"] is True
|
||||
obj = screens.get_scene_object(slug, object_id)
|
||||
assert screens.resolve_collision_rules(obj) == []
|
||||
|
||||
|
||||
def test_dispatch_move_trigger_action_swaps_a_leaf_up(client, tmp_game_slug_cleanup):
|
||||
slug, screen_id = _create_jeu2d_game(client, tmp_game_slug_cleanup)
|
||||
object_id = screens.add_scene_object(slug, screen_id, kind="decor")
|
||||
screens.set_scene_object_collision_rules(slug, object_id, screens.sanitize_collision_rules([{
|
||||
"trigger": "collision",
|
||||
"action": {
|
||||
"type": "variable", "id": "v_1", "target_variable": "score", "data_operation": "incrementer", "data_value": "1",
|
||||
"then": {"type": "dialogue", "dialogue": {"id": "d_1", "lines": []}},
|
||||
},
|
||||
}]))
|
||||
result = dispatch_tool(slug, screen_id, 1, "move_trigger_action", {"object_id": object_id, "leaf_id": "d_1", "direction": "up"})
|
||||
assert result["ok"] is True
|
||||
obj = screens.get_scene_object(slug, object_id)
|
||||
assert screens.resolve_collision_rules(obj)[0]["action"]["type"] == "dialogue"
|
||||
|
||||
|
||||
def test_dispatch_remove_screen_trigger_action_removes_a_leaf(client, tmp_game_slug_cleanup):
|
||||
slug, screen_id = _create_jeu2d_game(client, tmp_game_slug_cleanup)
|
||||
screens.set_screen_triggers(slug, screen_id, screens.sanitize_screen_triggers([
|
||||
{"trigger": "affichage", "action": {"type": "dialogue", "dialogue": {"id": "d_1", "lines": []}}},
|
||||
]))
|
||||
result = dispatch_tool(slug, screen_id, 1, "remove_screen_trigger_action", {"leaf_id": "d_1"})
|
||||
assert result["ok"] is True
|
||||
screen = screens.get_screen(slug, screen_id)
|
||||
assert screens.resolve_screen_triggers(screen) == []
|
||||
|
||||
|
||||
def test_dispatch_move_screen_trigger_action_swaps_a_leaf_up(client, tmp_game_slug_cleanup):
|
||||
slug, screen_id = _create_jeu2d_game(client, tmp_game_slug_cleanup)
|
||||
screens.set_screen_triggers(slug, screen_id, screens.sanitize_screen_triggers([{
|
||||
"trigger": "affichage",
|
||||
"action": {
|
||||
"type": "attendre", "id": "a_1", "data_value": "2",
|
||||
"then": {"type": "dialogue", "dialogue": {"id": "d_1", "lines": []}},
|
||||
},
|
||||
}]))
|
||||
result = dispatch_tool(slug, screen_id, 1, "move_screen_trigger_action", {"leaf_id": "d_1", "direction": "up"})
|
||||
assert result["ok"] is True
|
||||
screen = screens.get_screen(slug, screen_id)
|
||||
assert screens.resolve_screen_triggers(screen)[0]["action"]["type"] == "dialogue"
|
||||
|
||||
|
||||
def test_dispatch_tool_raises_for_an_unknown_tool_name(client, tmp_game_slug_cleanup):
|
||||
slug, screen_id = _create_jeu2d_game(client, tmp_game_slug_cleanup)
|
||||
try:
|
||||
@@ -269,6 +355,24 @@ def test_set_collision_rules_action_type_enum_matches_the_source_constant():
|
||||
assert action_schema["properties"]["type"]["enum"] == list(ACTION_TYPES)
|
||||
|
||||
|
||||
def test_set_collision_rules_trigger_enum_matches_the_source_constant():
|
||||
from screens.rendering.collision_rules import TRIGGER_TYPES
|
||||
rules_schema = _tool("set_collision_rules")["input_schema"]["properties"]["rules"]["items"]
|
||||
assert rules_schema["properties"]["trigger"]["enum"] == list(TRIGGER_TYPES)
|
||||
|
||||
|
||||
def test_set_screen_triggers_trigger_enum_matches_the_source_constant():
|
||||
from screens.rendering.screen_triggers import TRIGGER_TYPES_SCREEN
|
||||
rules_schema = _tool("set_screen_triggers")["input_schema"]["properties"]["rules"]["items"]
|
||||
assert rules_schema["properties"]["trigger"]["enum"] == list(TRIGGER_TYPES_SCREEN)
|
||||
|
||||
|
||||
def test_set_collision_rules_video_mode_enum_matches_the_source_constant():
|
||||
from screens.labels.video_modes import VIDEO_MODE_LABELS
|
||||
action_schema = _tool("set_collision_rules")["input_schema"]["properties"]["rules"]["items"]["properties"]["action"]
|
||||
assert set(action_schema["properties"]["mode"]["enum"]) == set(VIDEO_MODE_LABELS)
|
||||
|
||||
|
||||
def test_set_collision_rules_condition_operator_enum_matches_the_source_constant():
|
||||
from screens.rendering.collision_rules import CONDITION_OPERATOR_KEYS
|
||||
action_schema = _tool("set_collision_rules")["input_schema"]["properties"]["rules"]["items"]["properties"]["action"]
|
||||
|
||||
Reference in New Issue
Block a user