Dynamische Geräteauswahl
Einleitung
Anstelle der Schrauben, lassen sich Geräte auch hier via Namen ansprechen. Damit man im Menü nicht ständig alles einzeln schreiben muss, was sich nicht so leicht anpassen lässt, habe ich mir etwas überlegt:
Voraussetzungen
Zunächst einmal benötigt ihr global eine Liste der Geräte. Bei mir sieht die üblicherweise so aus:
local Settings = {
Devices = {
FURN = { prefab = ic.hash("StructureAdvancedFurnace"), name = ic.hash("Furn"), desc = "Furnace: ", allowed_types = { ic.hash("StructureAdvancedFurnace") } },
VP_IN_HOT = { prefab = ic.hash("StructureTurboVolumePump"), name = ic.hash("TVP.HOT"), desc = "Heißgaspumpe", allowed_types = { ic.hash("StructureTurboVolumePump"), ic.hash("StructureVolumePump") } },
VP_IN_WASTE = { prefab = ic.hash("StructureTurboVolumePump"), name = ic.hash("TVP.WASTE"), desc = "Wastegaspumpe", allowed_types = { ic.hash("StructureTurboVolumePump"), ic.hash("StructureVolumePump") } },
VP_IN_COLD = { prefab = ic.hash("StructureTurboVolumePump"), name = ic.hash("TVP.COLD"), desc = "Kaltgaspumpe", allowed_types = { ic.hash("StructureTurboVolumePump"), ic.hash("StructureVolumePump") } },
PA_TANK_HOT = { prefab = ic.hash("StructurePipeAnalysizer"), name = ic.hash("PA.TANK.HOT"), desc = "Tanksensor Heißgas", allowed_types = { ic.hash("StructurePipeAnalysizer")} },
PA_TANK_WASTE = { prefab = ic.hash("StructurePipeAnalysizer"), name = ic.hash("PA.TANK.WASTE"), desc = "Tanksensor Wastegas", allowed_types = { ic.hash("StructurePipeAnalysizer")} },
PA_TANK_COLD = { prefab = ic.hash("StructurePipeAnalysizer"), name = ic.hash("PA.TANK.COLD"), desc = "Tanksensor Kaltgas", allowed_types = { ic.hash("StructurePipeAnalysizer")} },
PA_WASTE = { prefab = ic.hash("StructurePipeAnalysizer"), name = ic.hash("PA.WASTE"), desc = "Sensor Wasteausgang", allowed_types = { ic.hash("StructurePipeAnalysizer")} },
VP_WASTE_OUT = { prefab = ic.hash("StructureTurboVolumePump"), name = ic.hash("TVP.WASTE.OUT"), desc = "Pumpe Wasteablass", allowed_types = { ic.hash("StructureTurboVolumePump"), ic.hash("StructureVolumePump") } },
VP_Oxidator = { prefab = ic.hash("StructureTurboVolumePump"), name = ic.hash("TVP.O2"), desc = "Pumpe Oxidator (O2)", allowed_types = { ic.hash("StructureTurboVolumePump"), ic.hash("StructureVolumePump") } },
VP_Reduktor = { prefab = ic.hash("StructureTurboVolumePump"), name = ic.hash("TVP.METHANE"), desc = "Pumpe Reduktor (Methane)", allowed_types = { ic.hash("StructureTurboVolumePump"), ic.hash("StructureVolumePump") } },
PA_Oxidator = { prefab = ic.hash("StructurePipeAnalysizer"), name = ic.hash("PA.O2"), desc = "Sensor Oxidator (O2)", allowed_types = { ic.hash("StructurePipeAnalysizer") } },
PA_Reduktor = { prefab = ic.hash("StructurePipeAnalysizer"), name = ic.hash("PA.METHANE"), desc = "Sensor Reduktor (Methane)",allowed_types = { ic.hash("StructurePipeAnalysizer") } },
IGN = { prefab = ic.hash("StructurePipeIgniter"), name = ic.hash("IGN"), desc = "Zünder für Gas", allowed_types = { ic.hash("StructurePipeIgniter")} },
VP_COLD_FILL = { prefab = ic.hash("StructurePoweredVentLarge"), name = ic.hash("PAV.COLD"), desc = "Kaltgas befüllung", allowed_types = { ic.hash("StructureTurboVolumePump"), ic.hash("StructureVolumePump"), ic.hash("StructurePoweredVentLarge"), ic.hash("StructurePoweredVent"), ic.hash("StructureActiveVent")} }
}
}
Diese liste enthält einmal den Hash des Gerätes (prefab), den Namenshash des Gerätes(name), eine Beschreibung für das Menü (desc) und eine Liste an Gerätetypen, die für diesen Einsatz zugelassen sind (allowed_types).
Hilfsfunktionen
Dann sind noch 3 globale Hilfsfunktionen notwendig:
local function in_array(array, value)
for _, v in ipairs(array) do
if v == value then
return true
end
end
return false
end
function getDeviceByRefId(ref_id)
local devices = ic.device_list()
for _, dev in ipairs(devices) do
if dev.ref_id == tonumber(ref_id) then
return dev
end
end
return nil
end
function getDeviceList(sel_prefab, sel_name, allowed)
local allowed_device_types = allowed or {}
local devices = ic.device_list()
local option_list = {}
local selected = 0
local help_i = 1
for i, dev in ipairs(devices) do
if #allowed_device_types > 0 then
if in_array(allowed_device_types, dev.prefab_hash) then
option_list[help_i] = dev.display_name .. " (ID: ".. dev.ref_id .. ")"
if dev.name_hash == sel_name and dev.prefab_hash == sel_prefab then
selected = help_i-1
end
help_i = help_i + 1
end
else
option_list[i] = dev.display_name .. " (ID: ".. dev.ref_id .. ")"
if dev.name_hash == sel_name and dev.prefab_hash == sel_prefab then
selected = i-1
end
end
end
return option_list, selected
end
Anzeige
Ich schreibe alle Anzeigen in eine Funktion, welche immer mit build* beginnt. Zusätzlich habe ich ein Array mit den vorhandenen Screens, daher verwende ich hier kein ui:element() sondern screen_surface:element(). Das könnt ihr aber anders handhaben!
function buildDevices()
local devs = Settings.Devices
local screen_surface = screens.devices.surface
local pos_x = 20
local pos_y = 30
print("Call: buildDevices()")
screen_surface:clear()
-- Background
screen_surface:element({ id = "bg", type = "panel",
rect = { unit = "px", x = 0, y = 0, w = W, h = H },
style = { bg = "#0B1120" }
})
-- Titel
screen_surface:element({ id = "head_title_text", type = "panel",
rect = { unit = "px", x = 0, y = 0, w = W, h = 20 },
style = { bg = "#44DD44" }
})
screen_surface:element({ id = "head_title_panel", type = "label",
rect = { unit = "px", x = 20, y = 0, w = W - 40, h = 20 },
props = { text = "Geräteliste" },
style = { font_size = 14, color = "#FFFFFF" }
})
for key, dev in pairs(devs) do
local ol, sel = getDeviceList(dev.prefab, dev.name, dev.allowed_types)
screen_surface:element({ id = "lbl_settings_temp1" .. key, type = "label",
rect = { unit = "px", x = pos_x, y = pos_y, w = 200, h = 20 },
props = { text = dev.desc },
style = { font_size = 12, color = "#FFFFFF" }
})
screen_surface:element({
id = "select" .. key, type = "select",
rect = { unit = "px", x = pos_x + 200, y = pos_y, w = W - pos_x - 210, h = 20 },
props = { options = ol, selected = sel },
style = { bg = "#0F172A", text = "#E2E8F0", font_size = 10 },
on_change = function(value, player)
local id = ol[tonumber(value)+1]:match("ID:%s*(%d+)")
local ref_dev = getDeviceByRefId(id)
if ref_dev == nil then
print("Gerät mit ID " .. id .. " nicht gefunden")
else
dev.prefab = ref_dev.prefab_hash
dev.name = ref_dev.name_hash
screen_surface:get("select" .. key):set_props({selected = tonumber(value)})
end
end,
})
pos_y = pos_y + 22
end
screen_surface:element({
id = "btn_settings_ok", type = "button",
rect = { unit = "px", x = pos_x, y = pos_y, w = W - pos_x - 20, h = 30 },
style = { bg = Colors.BTN_GREEN, text = "#FFFFFF" },
props = { text = "Fertig", z_index = 101 },
on_click = function(playerName)
saveSettings()
ss.ui.activate("settings")
end
})
screen_surface:commit()
end
Spannend ist für euch die Schleife welche in Zeile 28 beginnt. Diese durchläuft alle Geräte aus meiner globalen Liste. In Zeile 29 wird dann ein getDeviceList() ausgeführt. Dieses gibt mir einmal in ol die Objektliste zurück. Diese Liste kann ich 1:1 an den Select übergeben. Weiterhin erhalte ich unter sel den Index des Gerätes, welches aktuell in der globalen Liste ausgewählt ist (sofern dies existiert).
Zeile 30 bis 34 Erzeugt das Label mit der Beschreibung
Zeile 35 bis 51 Erzeugt das Auswahlmenü (select) dem ich unter props die ol und sel übergebe. Wenn man nun ein Objekt auswählt, wird nur ein Index über value in der on_change-Funktion ausgegeben. Daraus kann dann der ausgewählte Name ermittelt werden und in dem steckt die RefID des Gerätes. Diese wird über einen regex ausgelesen. Das alles passiert in Zeile 41 und dann landet die RefIDin id. Mit der RefID kann dann über die getDeviceByRefId Funktion nach dem Gerät gesucht werden. Ist das Gerät gefunden worden, werden der Gerätehash (prefabhash) und der Namenshash (namehash) in die globale Liste geschrieben.
Abschluss
Wie man es möchte, kann man dann auch gleich diese Liste abspeichern oder, so wie ich es im Beispiel gemacht habe, die Liste speichern, wenn man auf "Fertig" klickt. Ich hoffe, euch hat dies geholfen und es erleichtert euch ein wenig das Erstellen einer Geräteauswahl.
No comments to display
No comments to display