Benutzer-Werkzeuge

Webseiten-Werkzeuge


utilscripts:luainterpreter

Lua-Interpreter

Einführung

In DEdK kann Lua nicht vollständig verwendet werden. Auf der einen Seite wurden Funktionen (teilweise völlig sinnlos) deaktiviert, auf der anderen Seite wird der Lua-Status nicht richtig gespeichert bzw. geladen. Wie kann man also diese Probleme lösen?
Der einzige Weg, ein „vollständigeres“ Lua zu verwenden, ist, den Lua-Interpreter in Lua zu schreiben.

Lua in Lua

Der Original-C-Code von Lua (5.0.2) wurde von mir nach Lua übertragen. Dadurch war es möglich, einige Funktionen wieder zu reaktivieren. Die neuen Coroutines/Threads werden korrekt gespeichert, da sie keine C-Threads mehr sind, sondern eigentlich Lua-Tables. Auch Metatables werden in dieser Re-Implementierung korrekt abgespeichert.

Lua-Interpreter einbinden

Den Lua-Interpreter kann man hier finden. Das Archiv enthält 13 Dateien. 11 dieser Dateien implementieren den Interpreter, erkennbar am vorangestellten LuaInterpreter.
Die Datei HOK_NewTriggerSystem.lua enthält ein neues Trigger-System, dass das alte von BB ersetzen soll. Die letzte Datei HOK_MainLoader.lua lädt alle Dateien. Falls nötig, muss man die lokale Variable currFolder anpassen. Möchte man den Interpreter direkt ins Script hinzufügen, muss man den Inhalt der Dateien in der Ladereihenfolge in HOK_MainLoader.lua kopieren.

Lua-Code laden

Wie aber kann man diesen Interpreter verwenden?
Um Lua-Code zu laden, muss TriggerSystem.DoString() mit dem Code und, eventuell, mit einem Quellnamen aufgerufen werden. Dieser Code wird geladen und vom Lua-Interpreter ausgeführt.

Interaktion zwischen Alt-Lua und Neu-Lua

Die globalen Variablen bei Neu- und Alt-Lua sind nicht identisch.
Sollte ein Wert in den globalen Variablen bei Neu-Lua nil sein, so wird automatisch versucht, den Wert aus Alt-Lua zu laden.
Ein Wert kann von Neu-Lua nicht einfach in Alt-Lua gesetzt werden. Dies muss explizit getan werden. _GLOBALS repräsentiert die globalen Variablen von Alt-Lua.

Reaktivierte Funktionen

Folgende Funktionen wurden reaktiviert:

  1. loadstring()
  2. getfenv()
  3. setfenv()
  4. error()

Bekannte Probleme des Lua-Interpreters

  • Bei Fehlermeldungen wird meist statt einem Variablennamen „?“ angezeigt; die Zeilenzahl stimmt aber überein.
  • string.dump() kann kein Dump von Neu-Lua-Funktionen erstellen; genausowenig kann loadstring() Dumps laden.
  • An Fehlermeldungen hängt auch die Zeilennummer des Asserts (LuaState.lua:…) dran
  • Die Geschwindigkeit des Lua-Interpreters ist (logischerweise) deutlich niedriger wie die des Originals

Das Trigger-System

Vorteile

Für den Mapper selbst gibt es auf den ersten Blick keinen Unterschied. Die Trigger-Funktionen funktionieren (fast) alle wie immer. Wozu also?
Auf der einen Seite bietet das neue Trigger-System den entscheidenden Vorteil, dass die (Haupt-)Funktion eines Triggers/Jobs als Thread aufgerufen wird. Dies bedeutet, dass man die Funktionen Delay() und DelayShort() verwenden kann. Entscheidend ist, dass diese Threads auch gespeichert werden.
Auf der anderen Seite können problemlos neue Ereignisse hinzugefügt und ausgelöst werden. So wurden einige nicht-existente Ereignisse hinzugefügt.
Ein weiterer Vorteil ist, dass die Event-Funktionen immer, auch nach einem Delay(), dieselben Werte zurückgeben.

Interaktion von Alt-Lua

Mit TriggerSystem.AddNewEvent() können eigene Ereignisse hinzugefügt werden. Der einzige Parameter ist der Name des Ereignisses. Zurückgegeben wird die ID des Ereignises. Der Eintrag im Events-Table (von Neu-Lua) wird automatisch erstellt.

TriggerSystem.ExecuteEvent() löst ein Ereignis aus. Die Parameter sind die Ereignis-ID und, optional, ein Table, dass die Informationen für die Event-Funktionen enthält.

Ereignisse

Folgende Ereignisse sind vorhanden (mit Event-Funktionen)

Ereignis-NameBeschreibungEvent-Funktionen
LOGIC_EVENT_GAME_STARTEDWird ausgelöst, wenn das Spiel startet-
LOGIC_EVENT_EVERY_SECONDWird jede Sekunde ausgelöst-
LOGIC_EVENT_EVERY_TURNWird jeden Tick ausgelöst-
LOGIC_EVENT_DIPLOMACY_CHANGEDWird ausgelöst, wenn sich die Diplomatie ändertEvent.GetDiplomacyState() - Diplomatie-Status
Event.GetSourcePlayerID() - Spieler 1
Event.GetTargetPlayerID() - Spieler 2
LOGIC_EVENT_ENTITY_CREATEDWird ausgelöst, wenn ein Entity erstellt wirdEvent.GetEntityID() - ID des Entities
LOGIC_EVENT_ENTITY_DESTROYEDWird ausgelöst, wenn ein Entity zerstört wirdEvent.GetEntityID() - ID des Entities
LOGIC_EVENT_ENTITY_HURT_ENTITYWird ausgelöst, wenn ein Entity ein anderes verletztEvent.GetEntityID1() - Angreifer
Event.GetEntityID2() - Angegriffener
LOGIC_EVENT_ENTITY_IN_RANGE_OF_ENTITY???Event.GetEntityID1() - Entity-ID 1
Event.GetEntityID2() - Entity-ID 2
Event.GetDistance() - Abstand
LOGIC_EVENT_GOODS_TRADEDWird ausgelöst, wenn an einem Marktplatz gehandelt wurdeEvent.GetEntityID() - Marktplatz
Event.GetBuyResource() - Die gekaufte Resource
Event.GetBuyAmount() - Die Menge, die gekauft wurde
Event.GetSellResource() - Die verkaufte Resource
Event.GetSellAmount() - Die Menge, die verkauft wurde
LOGIC_EVENT_TRIBUTE_PAIDWird ausgelöst, wenn ein Tribut bezahlt wurdeEvent.GetTributeUniqueID() - Tribut-ID
Event.GetSourcePlayerID() - bezahlender Spieler
Event.GetTargetPlayerID() - Spieler, der Rohstoffe bekommt
LOGIC_EVENT_WEATHER_STATE_CHANGEDWird ausgelöst, wenn sich das Wetter ändertEvent.GetOldWeatherState() - altes Wetter
Event.GetNewWeatherState() - neues Wetter
LOGIC_EVENT_RESEARCH_DONEWird ausgelöst, wenn eine Technologie fertig erforscht wurde (gefixt)Event.GetTechnologyType() - Technologie-ID
Event.GetPlayerID() - erforschender Spieler
LOGIC_EVENT_UPGRADE_FINISHEDWird ausgelöst, wenn ein Gebäude fertig ausgebaut wurdeEvent.GetEntityID1() - alte ID
Event.GetEntityID2() - neue ID
LOGIC_EVENT_BUILDING_CONSTRUCTION_COMPLETEWird ausgelöst, wenn ein Gebäude fertiggestellt wirdEvent.GetEntityID() - ID des Gebäudes
Event.GetPlayerID() - bauender Spieler
LOGIC_EVENT_CANNON_CONSTRUCTION_COMPLETEWird ausgelöst, wenn eine Kanone fertiggestellt wirdEvent.GetEntityID() - ID der Kanone
LOGIC_EVENT_PLAYER_STATE_CHANGEDWird ausgelöst, wenn sich ein Spieler-Status ändertEvent.GetPlayerID() - Spieler
Event.GetPlayerState() - neuer Status
LOGIC_EVENT_PLAYER_DIEDWird ausgelöst, wenn ein Spieler keine Einheit mehr besitzt (gefixt)Event.GetPlayerID() - Spieler
utilscripts/luainterpreter.txt · Zuletzt geändert: 2021/09/18 19:15 (Externe Bearbeitung)