Contrat remote consommateur (extension RitnLibGui)¶
RitnLibGuiest une classe de base abstraite. Elle ne fait rien seule. C'est ton mod qui la sous-classe, remplit les quatre champs du contrat et enregistre l'interface remote.
Ce contrat est appliqué dans plusieurs mods (RitnMenuButton, RitnLobbyGame, RitnCharacters).
Ce que RitnLibGui attend de la sous-classe¶
| Champ | Fourni par | Valeur attendue |
|---|---|---|
self.gui[1] |
sous-classe | le conteneur (player.gui.center, etc.) — pas le frame racine |
self.gui_name |
sous-classe | slug logique du GUI (ex. "changer") — préfixe de tous les éléments |
self.gui_action |
sous-classe | { [gui_name] = { [action] = true, ... } } |
self.content |
sous-classe | table de chemins utilisée par :getElement() |
RitnLibGui.init ne remplit pas ces champs — c'est le constructeur de la sous-classe qui le fait.
RitnLibGui.init — ce qu'il initialise vraiment¶
mod_name— nom du mod (cible desremote.call)main_gui— suffix du frame racine, pas legui_name. Le nom complet en jeu =gui_name .. "-" .. main_gui(ex:"changer-frame-main")
Convention de nommage des éléments¶
RitnLibGuiElement(gui_name, type, name) génère un nom de la forme gui_name-type_normalisé-name :
"changer-frame-main" ← RitnLibGuiElement("changer", "frame", "main")
"changer-button-select" ← RitnLibGuiElement("changer", "button", "select")
"changer-listbox-items" ← RitnLibGuiElement("changer", "list-box", "items")
Types normalisés : "list-box" → "listbox", "drop-down" → "dropdown", "sprite-button" → "button", "text-box" → "textbox".
Dispatch des clics — comment ça marche¶
on_gui_click parse le nom de l'élément cliqué via le pattern "([^-]*)-?([^-]*)-?([^-]*)" :
→ action = element .. "-" .. name = "button-select"
RitnLibGui vérifie que self.gui_action[ui][action] existe, puis appelle :
Interface remote — signature exacte¶
remote.add_interface("mon-mod", {
["gui_action_" .. gui_name] = function(action, event)
-- action = "button-close", "button-confirm", etc.
-- event = EventData Factorio original
end,
})
⚠ La signature est
function(action, event)— pasfunction(player_index, element_name).
self.gui_action — table des actions autorisées¶
self.gui_action = {
["changer"] = { -- clé = gui_name
["button-select"] = true,
["button-close"] = true,
}
}
Les clés internes sont les action strings ("type-name"). Si une action n'est pas dans cette table, le dispatch est ignoré silencieusement.
Exemple complet — RitnCharacters¶
-- classes/RitnGuiChanger.lua
RitnGuiCharacterChanger = ritnlib.classFactory.newclass(RitnLibGui, function(self, event)
RitnLibGui.init(self, event, ritnlib.defines.characters.name, "frame-main")
self.object_name = "RitnGuiCharacterChanger"
self.gui_name = "changer"
self.gui_action = {
["changer"] = {
["button-select"] = true,
-- (open/close déclenchés par shortcut, pas par clic interne)
}
}
self.gui = { self.player.gui.center } -- conteneur, pas le frame
self.content = fGui.getContent()
end)
-- modules/storage.lua
remote.add_interface("RitnCharacters", {
["gui_action_changer"] = function(action, event)
if action == "button-select" then
RitnGuiCharacterChanger(event):action_select()
end
end,
})
self:getElement(type, name) — naviguer dans la GUI¶
getElement parcourt self.content[type][name] comme un chemin depuis self.gui[1], en préfixant chaque étape avec gui_name .. "-" :
-- content.list = { "frame-main", "frame-submain", "flow-selecter", "listbox-characters" }
local list = self:getElement("list")
-- → self.gui[1]["changer-frame-main"]["changer-frame-submain"]
-- ["changer-flow-selecter"]["changer-listbox-characters"]