Menus à cases
Un menu avec de vraies cases d’objets, comme un coffre. GaldurMenu place les cases et gère le Maj-clic des deux côtés ; GaldurContainerScreen dessine l’écran au thème Galdur.
Comment ça s’assemble
Un menu à cases a deux moitiés, comme dans Minecraft :
| Classe | Côté | Rôle |
|---|---|---|
GaldurMenu | client et serveur | La logique : quelles cases existent, où, et comment le Maj-clic déplace les objets. |
GaldurContainerScreen | client | L’écran : panneau du thème, cadres des cases, titres, animation d’ouverture. |
api.menu est le seul paquet de Galdur UI qui se charge sur un serveur dédié.
Écrire le menu
Hérite de GaldurMenu, ajoute les cases du conteneur, puis l’inventaire du joueur :
public class CrateMenu extends GaldurMenu { private final Container crate; public CrateMenu(int id, Inventory player) { // côté client this(id, player, new SimpleContainer(27)); } public CrateMenu(int id, Inventory player, Container crate) { // côté serveur super(MY_MENUS.CRATE.get(), id); this.crate = crate; addSlotGrid(crate, 0, 9, 3, 8, 18); // les cases du conteneur d’abord addPlayerInventory(player, 8, 84); // l’inventaire du joueur en dernier } @Override public boolean stillValid(Player player) { return crate.stillValid(player); }}Ajoute d’abord les cases du conteneur (addSlotGrid ou addSlot), puis l’inventaire du joueur (addPlayerInventory), une seule fois. Chaque case ajoutée avant l’inventaire compte comme une case du conteneur pour le Maj-clic. Ajouter une grille après l’inventaire lève une IllegalStateException.
Coordonnées
Les coordonnées sont celles de Minecraft : des pixels d’interface depuis le coin haut gauche du panneau, qui pointent sur le coin haut gauche de l’objet de 16 × 16. Le cadre de la case dépasse d’un pixel autour.
| Constante | Valeur | Sens |
|---|---|---|
SLOT_SIZE | 18 | Distance entre deux cases voisines : 16 pour l’objet, 2 pour les cadres. |
HOTBAR_GAP | 4 | Écart vertical entre les trois rangées d’inventaire et la barre d’action. |
addSlotGrid(container, firstIndex, columns, rows, x, y) remplit rangée par rangée, de gauche à droite. addPlayerInventory(inventory, x, y) ajoute trois rangées de neuf, puis la barre d’action HOTBAR_GAP pixels plus bas.
Enregistrer le type de menu
Enregistre le type de menu comme d’habitude avec le registre de ton loader. L’exemple utilise le DeferredRegister de NeoForge ; Galdur UI n’a besoin que du MenuType obtenu :
private static final DeferredRegister<MenuType<?>> MENUS = DeferredRegister.create(Registries.MENU, MyMod.MODID);public static final DeferredHolder<MenuType<?>, MenuType<CrateMenu>> CRATE = MENUS.register("crate", () -> new MenuType<>(CrateMenu::new, FeatureFlags.DEFAULT_FLAGS));Le constructeur client CrateMenu(int, Inventory) est celui que MenuType appelle côté client. Côté serveur, ouvre le menu avec ton conteneur, par exemple player.openMenu(new SimpleMenuProvider((id, inv, p) -> new CrateMenu(id, inv, crate), title)).
Enregistrer l’écran
Côté client. GaldurContainerScreen s’utilise tel quel, sans écrire de sous-classe, mais chaque loader enregistre ses écrans à sa façon : Galdur UI fournit donc une aide par loader. C’est la seule ligne de ce guide qui diffère selon le loader, et l’aide se trouve dans l’artefact du loader :
NeoForge :
// GaldurNeoForgeScreens : com.galdurstudio.galdurui.api.neoforgemodEventBus.addListener(RegisterMenuScreensEvent.class, event -> event.register(MY_MENUS.CRATE.get(), GaldurNeoForgeScreens.factory()));Forge :
// GaldurForgeScreens : com.galdurstudio.galdurui.api.forgemodEventBus.addListener((FMLClientSetupEvent event) -> GaldurForgeScreens.register(event, MY_MENUS.CRATE.get()));Fabric :
// GaldurFabricScreens : com.galdurstudio.galdurui.api.fabric// dans ton ClientModInitializerGaldurFabricScreens.register(MY_MENUS.CRATE);Un mod pour plusieurs loaders garde cette ligne dans son module de loader. Maj-clic, glisser-déposer, touches numériques, info-bulles des objets, panneau du thème et cadres des cases marchent sans autre code, pour n’importe quel menu, y compris ceux de Minecraft.
Sur Fabric, la case survolée reçoit le voile blanc de Minecraft au lieu du voile d’accent translucide, car ce point d’accroche n’existe que dans les versions NeoForge et Forge de Minecraft. Le contour d’accent est dessiné sur tous les loaders.
Ce que l’écran fait pour toi
- Taille du panneau déduite des cases : la marge à gauche de la première case est reprise à droite et en bas. Un menu sans case prend la taille d’un coffre vanilla (176 × 166).
- Libellé « Inventaire » juste au-dessus de l’inventaire du joueur quand le menu en a un, masqué sinon.
- Survol : la case survolée prend un voile translucide à la couleur d’accent et un contour
accent_hover, comme chaque case visée par une répartition au glisser. - Titre dans la police de la marque (Police de titre).
- Ouverture : le panneau monte légèrement à l’ouverture de l’écran.
- Narration : l’objet de la case survolée est lu (« Lingot de fer, 32 »), ce que Minecraft ne fait pas.
Personnaliser l’écran
Hérite de GaldurContainerScreen pour imposer une taille de panneau, ou ajouter du contenu :
public class CrateScreen extends GaldurContainerScreen<CrateMenu> { public CrateScreen(CrateMenu menu, Inventory inventory, Component title) { super(menu, inventory, title, 176, 190); // taille de panneau imposée } @Override protected void init() { super.init(); // ajoute tes widgets ici, par rapport à leftPos / topPos }}Redéfinis renderBg ou renderLabels pour dessiner plus. Si un bouton ou un onglet latéral dépasse du panneau, renvoie sa zone depuis getExclusionZones() pour que JEI et EMI la laissent libre.
La suite : afficher des milliers d’objets sans vraies cases avec Grilles d’objets et terminaux.