table.insert
table.insert (_Table, [_Index,] _Value)
Fügt einen numerischen Eintrag in das Table _Table
am Index _Index
(standardmäßig Größe des Tables + 1, also ans Ende) ein. Falls _Index
schon mit einem Wert belegt ist, wird dieser und alle nachfolgenden um einen Index nach oben verschoben.
Parameter
Name | Typ | Beschreibung |
---|---|---|
_Table | Numerisches Table | Table, in das der Wert _Value eingefügt werden soll |
_Index | Integer | Optionaler Parameter; Index, an dem der Wert _Value eingefügt werden soll. Standardmäig Größe des Tables + 1 (also ans Ende) |
_Value | Beliebig | Wert, der ins Table _Table eingefügt werden soll |
Rückgabewerte
Keine
Beispiele
Wir beginnen im ersten Beipiel damit, zu beobachten, wie sich table.insert
auf ein (leeres) Table auswirkt:
-- Beginne mit einem kleinen Table MyTable = {5} -- Füge einige Werte ein (ohne einen Index anzugeben, also ganz hinten) table.insert(MyTable, "Hallo Welt") table.insert(MyTable, 42) table.insert(MyTable, true) for Index, Value in ipairs(MyTable) do print(Index .. ": " .. tostring(Value)) end -- 1: 5 -- 2: Hallo Welt -- 3: 42 -- 4: true -- Gebe nun einen ganz bestimmten Index an, an der ein neuer Wert eingefügt werden soll -- Die Werte dahinter werden eins nach hinten rutschen table.insert(MyTable, 3, "6,50") for Index, Value in ipairs(MyTable) do print(Index .. ": " .. tostring(Value)) end -- 1: 5 -- 2: Hallo Welt -- 3: 6,50 -- 4: 42 -- 5: true
Im zweiten Beispiel soll eine zusätzliche Seite in ein Briefing eingefügt werden, die von einer bestimmten Bedingung abhängt. Bedenke, dass die Definition eines Briefings zum Großteil aus einem numerischen Table besteht, das die einzelnen Briefing-Seiten enthält.
Angenommen, der Spieler konnte in einer optionalen Quest einige Ordensritter befreien. Das Briefing, das dem Spieler kommuniziert, dass er das gegnerische Hauptquartier angreifen muss, soll darauf reagieren können:
function CreateBriefingClimax() local Briefing = { { title = "Mentor", text = "Herr, wir haben es fast geschafft! Die Mauern vor der feindlichen Burg sind überwunden - wir müssen nun stürmen!", position = GetPosition("EnemyWalls") }, { title = "Mentor", text = "Kerberos hat sich hierher zurückgezogen. Die Ratte sitzt im Käfig und hat noch nicht begriffen, dass sie in eine Falle lief.", position = GetPosition("EnemyHQ"), explore = 1000 }, restoreCamera = true } -- Das Briefing soll nun abhängig davon, ob der Spieler die Ordensritter befreit hat, eine dritte -- Seite bekommen -- Die Bedingung ist in der globalen Variable KnightOrderLiberated gespeichert if KnightOrderLiberated then -- Die neue Briefing-Seite soll an zweiter Stelle, also nach der ersten oben definierten Seite -- eingefügt werden -- Die ursprünglich zweite Seite rückt dafür automatisch an die dritte Stelle table.insert(Briefing, 2, { title = "Mentor", text = "Wir sind nicht allein! Die Ordensritter, die Ihr befreit habt, wollen an Eurer Seite kämpfen.", position = GetPosition("KnightOrderHQ"), dialogCamera = true } ) end StartBriefing(Briefing) end
Wir verwenden table.insert und table.remove in einem gemeinsamen Beispiel:
Der Spieler soll von einem Verbündeten einige Truppen erhalten. Während der Übergabe soll der Spieler die Truppen noch nicht steuern können (da sie noch der verbündeten Spieler-Id gehören), bis sie ihren Zielort erreicht haben. Dort sollen sie die Spieler-Id wechseln und in Richtung des gegnerischen Haupthauses mit dem Skriptnamen „EnemyHQ“
schauen. Es wird außerdem eine Spawnposition für die Truppen namens „AlliedSupportSpawn“
und drei Positionen, zu denen die erstellten Truppen gehen sollen („SupportPosition1“
bis „SupportPosition3“
) gebraucht.
Wichtig: In der Funktion ControlAlliedSupport
iterieren wir rückwärts durch das Table (von n
in -1
-Schritten bis 1
), um ggf. Einträge mit table.remove
zu löschen. Das hat folgenden Grund: Wenn mit table.remove Einträge aus einer Liste gelöscht werden, rücken die Einträge dahinter nach, um die entstandene Lücke zu füllen (die nachfolgenden Indizes werden also alle um 1 reduziert). Würden wir wie gewohnt vorwärts iterieren und ein Element an Stelle i
löschen, würde das darauf folgende Element auf Stelle i
vorrücken. Da die Iteration aber bei i+1
weiter geht, hätten wir dadurch ein Element übersprungen. Rückwärts kann das nicht passieren, da das Element an Index i-1
von table.remove
nicht beeinflusst wird.
function CreateAlliedSupport() -- Wir definieren, welche Truppen wo erstellt werden und wohin sie laufen sollen -- Diese Liste kann beliebig erweitert werden, wir beschränken uns der Übersicht zuliebe -- aber auf 3 Truppen local TroopDescriptions = { { LeaderType = Entities.PU_LeaderSword3, Target = "SupportPosition1" }, { LeaderType = Entities.PU_LeaderBow2, Target = "SupportPosition2" }, { LeaderType = Entities.PU_LeaderBow2, Target = "SupportPosition3" }, } -- Ein globales Table, in dem die Entity-Namen der Hauptmänner und die Positionen, zu denen sie sich -- bewegen sollen, gespeichert werden -- Dieses Table wird dann dazu benutzt, alle Truppen zu der Position zu bewegen und, wenn sie angekommen -- sind, dem Spieler zu übergeben AlliedSupportTroops = {} -- Verwendung von ipairs, um über TroopDescriptions zu iterieren, da es ein numerisches Table ist for i, TroopDescription in ipairs(TroopDescriptions) do -- Der Name des Hauptmanns setzt sich aus "SupportTroop" und dem Index der TroopDescription zusammen local EntityName = "SupportTroop" .. i CreateMilitaryGroup(4, TroopDescription.LeaderType, 4, GetPosition("AlliedSupportSpawn"), EntityName) -- Hier wird in das globale Table AlliedSupportTroops ein neuer Eintrag gesetzt, der den Entity-Namen -- und sein Laufziel enthält table.insert(AlliedSupportTroops, { Name = EntityName, Target = TroopDescription.Target } ) end -- Ein SimpleJob, der die erstellten Truppen zu ihrem Ziel laufen lassen soll StartSimpleJob("ControlAlliedSupport") end function ControlAlliedSupport() -- Es reicht, wenn wir die Truppen alle 5 Sekunden auf das Ziel zubewegen bzw. deren Ankunft prüfen if not Counter.Tick2("ControlAlliedSupportCounter", 5) then return end -- Angekommene Truppen werden aus dem Table gelöscht (siehe unten) -- Folglich können wir den Job beenden, wenn das Table leer ist (und das Table löschen) if table.getn(AlliedSupportTroops) == 0 then AlliedSupportTroops = nil return true end -- Wir iterieren RÜCKWÄRTS (s.o.) durch das Table und prüfen, ob ein Trupp an seiner Zielposition angekommen ist -- Wenn ja, wird er dem Spieler übergeben und er richtet sich auf "EnemyHQ" aus -- Andernfalls bekommt er einen (erneuten) Laufbefehl for i = table.getn(AlliedSupportTroops), 1, -1 do local SupportTroop = AlliedSupportTroops[i] if IsNear(SupportTroop.Name, SupportTroop.Target, 500) then ChangePlayer(SupportTroop.Name, 1) LookAt(SupportTroop.Name, "EnemyHQ") -- Lösche den i-ten Eintrag, also den Trupp, der am Ziel ist, aus dem Table table.remove(AlliedSupportTroops, i) else Move(SupportTroop.Name, SupportTroop.Target) end end end
Verwendete Funktionen: