Fiche MAPDL1-L4-CART-01 — Niveau N2 — Modèle prévu opus medium | utilisé claude-opus-5-5 — Agent session « Medium · MAPDL1 » — Skills sk-protocol, lp-city, lp-commandlets # MAPDL1-L4 (préparation) : comment le menu décide qu'une ville est « Installed » (2026-10-22) Lecture demandée par Big Boss pour démarrer L4 aussitôt. Commandlets en lecture seule, sous le jeton UE de P1. ## 1. Mesuré - `LPDumpFunction -BP=City` : `=== City : 1 graphe(s) === / EventGraph (75 noeuds)`. - `LPDumpFunction -BP=City -Fn=EventGraph -Pins -Exec` : 349 lignes, dans `etat\REL\MAPDL1\MAPDL1-L4-dump-City-EventGraph.txt`. Journal : `Saved\Logs\portage\MAPDL1_LPDumpFunction_20261022-115942.log`. - `LPDumpFunction -BP=CityMenu -Fn=EventGraph -Pins -Exec` : 264 lignes, dans `etat\REL\MAPDL1\MAPDL1-L4-dump-CityMenu-EventGraph.txt`. Journal : `…_20261022-120130.log`. Extraits, avec les lignes des fichiers ci-dessus : ``` CityMenu.EventGraph l. 123-132 : K2Node_CallFunction_7 appel ModdingExtraBPLibrary::GetAllFilesFromFolder() Files -> K2Node_VariableSet_20.SM_Data RootFolderFullPath = 'Heavy/StreetMap' Ext = 'uasset' City.EventGraph l. 2-4, 45-49 : Construct -> CityText.SetText(City.DisplayName) -> Delay 0.2 City.EventGraph l. 164-181 : String = '/' + + '.uasset' City.EventGraph l. 168-225 : ForEachLoopWithBreak sur CityMenu.SM_Data ; EndsWith(element, String, IgnoreCase) -> Count++ ; Count == 2 -> InstalledText.SetText(…) + SetColorAndOpacity(R=0.176, G=1, B=0 : vert), Break City.EventGraph l. 5-22, 96-104 : CityButton.OnClicked -> si InstalledText.GetText() == FormatText(…) -> CityMenu.CheckIfValidProportion -> SetLoading -> MoveCity ``` Source C++ de la liste : `Plugins/ModdingExtra/Source/ModdingExtra/Private/ModdingExtraBPLibrary.cpp:153-224`. - La fonction cherche d'abord les fichiers `*.uasset` sur le disque, sous `Content/Heavy/StreetMap` (`FindFilesRecursive`, l. 180). - Si la liste est vide, ce qui est le cas d'un build IoStore, elle la reconstruit **depuis le registre d'assets**, `GetAssetsByPath("/Game/Heavy/StreetMap", récursif)`, l. 186-218 (lot O2b). ## 2. Ce qui est établi - Une ville est **« Installed »** quand `SM_Data` contient **deux** chemins qui finissent par `/.uasset` : `StreetMap/` et `Static/`. C'est le mécanisme d'origine, celui de « How_to_install_a_city.txt » (copier les deux paires dans `Content\Heavy\StreetMap`). Sinon le texte reste celui du widget, « Not Installed » (`L1-CART-02`). - **Le clic est déjà bloqué** pour une ville « Not Installed » : `MoveCity` n'est appelé que si `InstalledText` vaut le texte « installé ». La décision D4 (« une ville reste indisponible tant que pas installée ») existe donc **déjà dans le Blueprint d'origine**. - Aujourd'hui, les 277 gabarits ont leurs deux `.uasset` : **toutes les villes apparaissent « Installed »**. - Les packs `lpm_city_*` sont sous `//StreetMap/…`, **hors de** `/Game/Heavy/StreetMap`. `SM_Data` ne les voit pas. Une ville servie seulement par un pack n'a l'état « Installed » que parce que son gabarit existe. ## 3. Conséquence pour L4 (à rédiger en SPEC, sans code avant GO) Le levier le plus simple est **C++, sans Blueprint** : `GetAllFilesFromFolder("Heavy/StreetMap", "uasset")`, qui ne sert que `CityMenu` pour ce dossier (à confirmer par recherche dans les autres Blueprints). 1. Il **retire** de la liste les gabarits, c'est-à-dire les villes sans pack et sans données réelles. Le critère reste à fixer en SPEC : - liste blanche des villes pleines du jeu (CentralLondon, 00BathCC) ; - ou repère du gabarit (maillage `Static/` de 98 Ko, ou étiquette du registre d'assets) ; - ou ville absente de `ResolveCityPath`. 2. Il **ajoute** `…/StreetMap/.uasset` et `…/Static/.uasset` pour chaque ville redirigée par un pack `lpm_city_*` monté. Ce qui en découle : - le menu d'origine affiche lui-même « Installed » ou « Not Installed », et bloque le clic : D4 est satisfait sans décoration ; - il reste à décorer en C++ : le **tri** (installées, téléchargeables, autres ; enfants de `CityScrollBox`) et le **bouton Download**, ou bien le texte « Download » sur `InstalledText` relayé à la fenêtre Slate. Attention : - `InstalledText` est aussi réécrit par `SetLoading` (bleu) et lu au clic : notre texte « Download » ne doit pas être égal au texte « installé » ; - le texte du `FormatText` comparé au clic n'est pas affiché par le dump (« Format (vide) »). Il faut le lire avant L4 (`uasset58.py strings` ou MCP). ## 4. Compte rendu - **Résultat** : le calcul « Installed » est établi. Ce sont deux fichiers `.uasset` dans la liste de `GetAllFilesFromFolder("Heavy/StreetMap")`. Le clic est bloqué pour une ville non installée. Le levier de L4 est cette fonction C++. - **Incertitudes** : - texte exact comparé au clic ; - autres appelants de `GetAllFilesFromFolder` sur `Heavy/StreetMap` ; - critère du gabarit. - **Fichiers** : `MAPDL1-L4-CART-01.md` (A). Les deux dumps `.txt` sont dans `etat\REL\MAPDL1\`, non suivis par git (`.gitignore`, `.txt` d'`etat`). - **À verser** : `lp-city` § 3 : l'état « Installed » du menu des villes est calculé par `GetAllFilesFromFolder("Heavy/StreetMap","uasset")` (`ModdingExtraBPLibrary.cpp:153`), avec deux `.uasset` par ville. Les packs `lpm_city_*` n'y figurent pas. - **Suite** : SPEC de L4 après les décisions D10 et D11.