mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
changed the system to make use of JSON files
This commit is contained in:
parent
373924a959
commit
ed92e9afb9
2
.gitignore
vendored
2
.gitignore
vendored
@ -21,5 +21,3 @@ logs/
|
||||
qt_ui/logs/liberation.log
|
||||
|
||||
*.psd
|
||||
resources/plugins/custom/__plugins.lst
|
||||
resources/plugins/custom/*.lua
|
||||
|
||||
@ -28,7 +28,7 @@ from .event.event import Event, UnitsDeliveryEvent
|
||||
from .event.frontlineattack import FrontlineAttackEvent
|
||||
from .infos.information import Information
|
||||
from .settings import Settings
|
||||
from plugin import INSTALLED_PLUGINS
|
||||
from plugin import LuaPluginManager
|
||||
|
||||
COMMISION_UNIT_VARIETY = 4
|
||||
COMMISION_LIMITS_SCALE = 1.5
|
||||
@ -220,8 +220,7 @@ class Game:
|
||||
ObjectiveDistanceCache.set_theater(self.theater)
|
||||
|
||||
# set the settings in all plugins
|
||||
for pluginName in INSTALLED_PLUGINS:
|
||||
plugin = INSTALLED_PLUGINS[pluginName]
|
||||
for plugin in LuaPluginManager().getPlugins():
|
||||
plugin.setSettings(self.settings)
|
||||
|
||||
def pass_turn(self, no_action=False):
|
||||
|
||||
@ -31,7 +31,7 @@ from gen.triggergen import TRIGGER_RADIUS_MEDIUM, TriggersGenerator
|
||||
from theater import ControlPoint
|
||||
from .. import db
|
||||
from ..debriefing import Debriefing
|
||||
from plugin import BasePlugin, INSTALLED_PLUGINS
|
||||
from plugin import LuaPluginManager
|
||||
|
||||
class Operation:
|
||||
attackers_starting_position = None # type: db.StartingPosition
|
||||
@ -146,10 +146,7 @@ class Operation:
|
||||
if not scriptFileMnemonic in self.listOfPluginsScripts:
|
||||
self.listOfPluginsScripts.append(scriptFileMnemonic)
|
||||
|
||||
if pluginName == None:
|
||||
pluginName = "custom"
|
||||
plugin_path = Path("./resources/plugins",pluginName)
|
||||
logging.debug(f"plugin_path = {plugin_path}")
|
||||
|
||||
if scriptFile != None:
|
||||
scriptFile_path = Path(plugin_path, scriptFile)
|
||||
@ -469,8 +466,7 @@ dcsLiberation.TargetPoints = {
|
||||
# Inject Plugins Lua Scripts and data
|
||||
self.listOfPluginsScripts = []
|
||||
|
||||
for pluginName in INSTALLED_PLUGINS:
|
||||
plugin = INSTALLED_PLUGINS[pluginName]
|
||||
for plugin in LuaPluginManager().getPlugins():
|
||||
plugin.injectScripts(self)
|
||||
plugin.injectConfiguration(self)
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from plugin import INSTALLED_PLUGINS
|
||||
from plugin import LuaPluginManager
|
||||
|
||||
class Settings:
|
||||
|
||||
@ -41,8 +41,7 @@ class Settings:
|
||||
|
||||
# LUA Plugins system
|
||||
self.plugins = {}
|
||||
for pluginName in INSTALLED_PLUGINS:
|
||||
plugin = INSTALLED_PLUGINS[pluginName]
|
||||
for plugin in LuaPluginManager().getPlugins():
|
||||
plugin.setSettings(self)
|
||||
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@ from gen.ground_forces.ai_ground_planner import (
|
||||
from .callsigns import callsign_for_support_unit
|
||||
from .conflictgen import Conflict
|
||||
from .ground_forces.combat_stance import CombatStance
|
||||
from plugin import INSTALLED_PLUGINS
|
||||
from plugin import LuaPluginManager
|
||||
|
||||
SPREAD_DISTANCE_FACTOR = 0.1, 0.3
|
||||
SPREAD_DISTANCE_SIZE_FACTOR = 0.1
|
||||
@ -140,7 +140,8 @@ class GroundConflictGenerator:
|
||||
self.plan_action_for_groups(self.enemy_stance, enemy_groups, player_groups, self.conflict.heading - 90, self.conflict.to_cp, self.conflict.from_cp)
|
||||
|
||||
# Add JTAC
|
||||
useJTAC = INSTALLED_PLUGINS and INSTALLED_PLUGINS["JtacAutolasePlugin"] and INSTALLED_PLUGINS["JtacAutolasePlugin"].isEnabled()
|
||||
jtacPlugin = LuaPluginManager().getPlugin("jtacautolase")
|
||||
useJTAC = jtacPlugin and jtacPlugin.isEnabled()
|
||||
if "has_jtac" in self.game.player_faction and self.game.player_faction["has_jtac"] and useJTAC:
|
||||
n = "JTAC" + str(self.conflict.from_cp.id) + str(self.conflict.to_cp.id)
|
||||
code = 1688 - len(self.jtacs)
|
||||
|
||||
@ -1,10 +1,2 @@
|
||||
from .base_plugin import BasePlugin
|
||||
from .veaf_plugin import VeafPlugin
|
||||
from .jtacautolase_plugin import JtacAutolasePlugin
|
||||
from .liberation_plugin import LiberationPlugin
|
||||
|
||||
INSTALLED_PLUGINS={
|
||||
"VeafPlugin": VeafPlugin(),
|
||||
"JtacAutolasePlugin": JtacAutolasePlugin(),
|
||||
"LiberationPlugin": LiberationPlugin(),
|
||||
}
|
||||
from .luaplugin import LuaPlugin
|
||||
from .manager import LuaPluginManager
|
||||
@ -1,48 +0,0 @@
|
||||
from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QPoint
|
||||
from PySide2.QtWidgets import QLabel, QDialog, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \
|
||||
QAbstractItemView, QPushButton, QGroupBox, QCheckBox, QVBoxLayout, QSpinBox
|
||||
|
||||
class BasePlugin():
|
||||
nameInUI:str = "Base plugin"
|
||||
nameInSettings:str = "plugin.base"
|
||||
enabledDefaultValue:bool = False
|
||||
|
||||
def __init__(self):
|
||||
self.uiWidget: QCheckBox = None
|
||||
self.enabled = self.enabledDefaultValue
|
||||
self.settings = None
|
||||
|
||||
def setupUI(self, settingsWindow, row:int):
|
||||
self.settings = settingsWindow.game.settings
|
||||
|
||||
self.uiWidget = QCheckBox()
|
||||
self.uiWidget.setChecked(self.isEnabled())
|
||||
self.uiWidget.toggled.connect(lambda: self.applySetting(settingsWindow))
|
||||
|
||||
settingsWindow.pluginsGroupLayout.addWidget(QLabel(self.nameInUI), row, 0)
|
||||
settingsWindow.pluginsGroupLayout.addWidget(self.uiWidget, row, 1, Qt.AlignRight)
|
||||
|
||||
def setSettings(self, settings):
|
||||
self.settings = settings
|
||||
if not self.nameInSettings in self.settings.plugins:
|
||||
self.settings.plugins[self.nameInSettings] = self.enabledDefaultValue
|
||||
|
||||
def applySetting(self, settingsWindow):
|
||||
self.settings.plugins[self.nameInSettings] = self.uiWidget.isChecked()
|
||||
self.enabled = self.settings.plugins[self.nameInSettings]
|
||||
|
||||
def injectScripts(self, operation):
|
||||
self.settings = operation.game.settings
|
||||
return self.isEnabled()
|
||||
|
||||
def injectConfiguration(self, operation):
|
||||
self.settings = operation.game.settings
|
||||
return self.isEnabled()
|
||||
|
||||
def isEnabled(self) -> bool:
|
||||
if not self.settings:
|
||||
return False
|
||||
|
||||
self.setSettings(self.settings) # create the necessary settings keys if needed
|
||||
|
||||
return self.settings != None and self.settings.plugins[self.nameInSettings]
|
||||
@ -1,95 +0,0 @@
|
||||
from dcs.triggers import TriggerStart
|
||||
from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QPoint
|
||||
from PySide2.QtWidgets import QLabel, QDialog, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \
|
||||
QAbstractItemView, QPushButton, QGroupBox, QCheckBox, QVBoxLayout, QSpinBox
|
||||
from .base_plugin import BasePlugin
|
||||
|
||||
class JtacAutolasePlugin(BasePlugin):
|
||||
nameInUI:str = "JTAC Autolase"
|
||||
nameInSettings:str = "plugin.jtacAutolase"
|
||||
enabledDefaultValue:bool = True
|
||||
|
||||
#Allow spawn option
|
||||
nameInUI_useSmoke:str = "JTACs use smoke"
|
||||
nameInSettings_useSmoke:str = "plugin.jtacAutolase.useSmoke"
|
||||
enabledDefaultValue_useSmoke:bool = True
|
||||
|
||||
def setupUI(self, settingsWindow, row:int):
|
||||
# call the base method to add the plugin selection checkbox
|
||||
super().setupUI(settingsWindow, row)
|
||||
|
||||
if settingsWindow.pluginsOptionsPageLayout:
|
||||
self.optionsGroup = QGroupBox(self.nameInUI)
|
||||
optionsGroupLayout = QGridLayout();
|
||||
optionsGroupLayout.setAlignment(Qt.AlignTop)
|
||||
self.optionsGroup.setLayout(optionsGroupLayout)
|
||||
settingsWindow.pluginsOptionsPageLayout.addWidget(self.optionsGroup)
|
||||
|
||||
# JTAC use smoke
|
||||
if not self.nameInSettings_useSmoke in self.settings.plugins:
|
||||
self.settings.plugins[self.nameInSettings_useSmoke] = True
|
||||
|
||||
self.uiWidget_useSmoke = QCheckBox()
|
||||
self.uiWidget_useSmoke.setChecked(self.settings.plugins[self.nameInSettings_useSmoke])
|
||||
self.uiWidget_useSmoke.toggled.connect(lambda: self.applySetting(settingsWindow))
|
||||
|
||||
optionsGroupLayout.addWidget(QLabel(self.nameInUI_useSmoke), 0, 0)
|
||||
optionsGroupLayout.addWidget(self.uiWidget_useSmoke, 0, 1, Qt.AlignRight)
|
||||
|
||||
# disable or enable the UI in the plugins special page
|
||||
self.enableOptionsGroup()
|
||||
|
||||
def enableOptionsGroup(self):
|
||||
pluginEnabled = self.uiWidget.isChecked()
|
||||
self.optionsGroup.setEnabled(pluginEnabled)
|
||||
|
||||
def setSettings(self, settings):
|
||||
# call the base method
|
||||
super().setSettings(settings)
|
||||
if not self.nameInSettings_useSmoke in self.settings.plugins:
|
||||
self.settings.plugins[self.nameInSettings_useSmoke] = self.enabledDefaultValue_useSmoke
|
||||
|
||||
def applySetting(self, settingsWindow):
|
||||
# call the base method to apply the plugin selection checkbox value
|
||||
super().applySetting(settingsWindow)
|
||||
|
||||
# save the "use smoke" option
|
||||
self.settings.plugins[self.nameInSettings_useSmoke] = self.uiWidget_useSmoke.isChecked()
|
||||
|
||||
# disable or enable the UI in the plugins special page
|
||||
self.enableOptionsGroup()
|
||||
|
||||
def injectScripts(self, operation):
|
||||
if super().injectScripts(operation):
|
||||
operation.injectPluginScript("jtacautolase", "JTACAutoLase.lua", "jtacautolase")
|
||||
|
||||
def injectConfiguration(self, operation):
|
||||
if super().injectConfiguration(operation):
|
||||
|
||||
# add a configuration for JTACAutoLase and start lasing for all JTACs
|
||||
smoke = "local smoke = false"
|
||||
if self.isUseSmoke():
|
||||
smoke = "local smoke = true"
|
||||
|
||||
lua = smoke + """
|
||||
|
||||
-- setting and starting JTACs
|
||||
env.info("DCSLiberation|: setting and starting JTACs")
|
||||
|
||||
for _, jtac in pairs(dcsLiberation.JTACs) do
|
||||
if dcsLiberation.JTACAutoLase then
|
||||
dcsLiberation.JTACAutoLase(jtac.dcsUnit, jtac.code, smoke, 'vehicle')
|
||||
end
|
||||
end
|
||||
"""
|
||||
|
||||
operation.injectLuaTrigger(lua, "Setting and starting JTACs")
|
||||
|
||||
def isUseSmoke(self) -> bool:
|
||||
if not self.settings:
|
||||
return False
|
||||
|
||||
self.setSettings(self.settings) # create the necessary settings keys if needed
|
||||
|
||||
return self.settings.plugins[self.nameInSettings_useSmoke]
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
from .base_plugin import BasePlugin
|
||||
|
||||
class LiberationPlugin(BasePlugin):
|
||||
nameInUI:str = "Liberation script"
|
||||
nameInSettings:str = "plugin.liberation"
|
||||
enabledDefaultValue:bool = True
|
||||
|
||||
def setupUI(self, settingsWindow, row:int):
|
||||
# Don't setup any UI, this plugin is mandatory
|
||||
pass
|
||||
|
||||
def injectScripts(self, operation):
|
||||
if super().injectScripts(operation):
|
||||
operation.injectPluginScript("base", "mist_4_3_74.lua", "mist")
|
||||
operation.injectPluginScript("base", "json.lua", "json")
|
||||
operation.injectPluginScript("base", "dcs_liberation.lua", "liberation")
|
||||
|
||||
def injectConfiguration(self, operation):
|
||||
if super().injectConfiguration(operation):
|
||||
pass
|
||||
|
||||
def isEnabled(self) -> bool:
|
||||
return True # mandatory plugin
|
||||
199
plugin/luaplugin.py
Normal file
199
plugin/luaplugin.py
Normal file
@ -0,0 +1,199 @@
|
||||
from typing import List
|
||||
from pathlib import Path
|
||||
from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QPoint
|
||||
from PySide2.QtWidgets import QLabel, QDialog, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \
|
||||
QAbstractItemView, QPushButton, QGroupBox, QCheckBox, QVBoxLayout, QSpinBox
|
||||
import json
|
||||
|
||||
class LuaPluginWorkOrder():
|
||||
|
||||
def __init__(self, parent, filename:str, mnemonic:str, disable:bool):
|
||||
self.filename = filename
|
||||
self.mnemonic = mnemonic
|
||||
self.disable = disable
|
||||
self.parent = parent
|
||||
|
||||
def work(self, mnemonic:str, operation):
|
||||
if self.disable:
|
||||
operation.bypassPluginScript(self.parent.mnemonic, self.mnemonic)
|
||||
else:
|
||||
operation.injectPluginScript(self.parent.mnemonic, self.filename, self.mnemonic)
|
||||
|
||||
class LuaPluginSpecificOption():
|
||||
|
||||
def __init__(self, parent, mnemonic:str, nameInUI:str, defaultValue:bool):
|
||||
self.mnemonic = mnemonic
|
||||
self.nameInUI = nameInUI
|
||||
self.defaultValue = defaultValue
|
||||
self.parent = parent
|
||||
|
||||
class LuaPlugin():
|
||||
NAME_IN_SETTINGS_BASE:str = "plugins."
|
||||
|
||||
def __init__(self, jsonFilename:str):
|
||||
self.mnemonic:str = None
|
||||
self.skipUI:bool = False
|
||||
self.nameInUI:str = None
|
||||
self.nameInSettings:str = None
|
||||
self.defaultValue:bool = False
|
||||
self.specificOptions = []
|
||||
self.scriptsWorkOrders: List[LuaPluginWorkOrder] = None
|
||||
self.configurationWorkOrders: List[LuaPluginWorkOrder] = None
|
||||
self.initFromJson(jsonFilename)
|
||||
self.enabled = self.defaultValue
|
||||
self.settings = None
|
||||
|
||||
def initFromJson(self, jsonFilename:str):
|
||||
jsonFile:Path = Path(jsonFilename)
|
||||
if jsonFile.exists():
|
||||
jsonData = json.loads(jsonFile.read_text())
|
||||
self.mnemonic = jsonData.get("mnemonic")
|
||||
self.skipUI = jsonData.get("skipUI", False)
|
||||
self.nameInUI = jsonData.get("nameInUI")
|
||||
self.nameInSettings = LuaPlugin.NAME_IN_SETTINGS_BASE + self.mnemonic
|
||||
self.defaultValue = jsonData.get("defaultValue", False)
|
||||
self.specificOptions = []
|
||||
for jsonSpecificOption in jsonData.get("specificOptions"):
|
||||
mnemonic = jsonSpecificOption.get("mnemonic")
|
||||
nameInUI = jsonSpecificOption.get("nameInUI", mnemonic)
|
||||
defaultValue = jsonSpecificOption.get("defaultValue")
|
||||
self.specificOptions.append(LuaPluginSpecificOption(self, mnemonic, nameInUI, defaultValue))
|
||||
self.scriptsWorkOrders = []
|
||||
for jsonWorkOrder in jsonData.get("scriptsWorkOrders"):
|
||||
file = jsonWorkOrder.get("file")
|
||||
mnemonic = jsonWorkOrder.get("mnemonic")
|
||||
disable = jsonWorkOrder.get("disable", False)
|
||||
self.scriptsWorkOrders.append(LuaPluginWorkOrder(self, file, mnemonic, disable))
|
||||
self.configurationWorkOrders = []
|
||||
for jsonWorkOrder in jsonData.get("configurationWorkOrders"):
|
||||
file = jsonWorkOrder.get("file")
|
||||
mnemonic = jsonWorkOrder.get("mnemonic")
|
||||
disable = jsonWorkOrder.get("disable", False)
|
||||
self.configurationWorkOrders.append(LuaPluginWorkOrder(self, file, mnemonic, disable))
|
||||
|
||||
def setupUI(self, settingsWindow, row:int):
|
||||
# set the game settings
|
||||
self.settings = settingsWindow.game.settings
|
||||
|
||||
if not self.skipUI:
|
||||
# create the plugin choice checkbox interface
|
||||
self.uiWidget: QCheckBox = QCheckBox()
|
||||
self.uiWidget.setChecked(self.isEnabled())
|
||||
self.uiWidget.toggled.connect(lambda: self.applySetting(settingsWindow))
|
||||
|
||||
settingsWindow.pluginsGroupLayout.addWidget(QLabel(self.nameInUI), row, 0)
|
||||
settingsWindow.pluginsGroupLayout.addWidget(self.uiWidget, row, 1, Qt.AlignRight)
|
||||
|
||||
# if needed, create the plugin options special page
|
||||
if settingsWindow.pluginsOptionsPageLayout and self.specificOptions != None:
|
||||
self.optionsGroup: QGroupBox = QGroupBox(self.nameInUI)
|
||||
optionsGroupLayout = QGridLayout();
|
||||
optionsGroupLayout.setAlignment(Qt.AlignTop)
|
||||
self.optionsGroup.setLayout(optionsGroupLayout)
|
||||
settingsWindow.pluginsOptionsPageLayout.addWidget(self.optionsGroup)
|
||||
|
||||
# browse each option in the specific options list
|
||||
row = 0
|
||||
for specificOption in self.specificOptions:
|
||||
nameInSettings = self.nameInSettings + specificOption.mnemonic
|
||||
if not nameInSettings in self.settings.plugins:
|
||||
self.settings.plugins[nameInSettings] = specificOption.defaultValue
|
||||
|
||||
specificOption.uiWidget = QCheckBox()
|
||||
specificOption.uiWidget.setChecked(self.settings.plugins[nameInSettings])
|
||||
#specificOption.uiWidget.setEnabled(False)
|
||||
specificOption.uiWidget.toggled.connect(lambda: self.applySetting(settingsWindow))
|
||||
|
||||
optionsGroupLayout.addWidget(QLabel(specificOption.nameInUI), row, 0)
|
||||
optionsGroupLayout.addWidget(specificOption.uiWidget, row, 1, Qt.AlignRight)
|
||||
|
||||
row += 1
|
||||
|
||||
# disable or enable the UI in the plugins special page
|
||||
self.enableOptionsGroup()
|
||||
|
||||
def enableOptionsGroup(self):
|
||||
if self.optionsGroup:
|
||||
self.optionsGroup.setEnabled(self.isEnabled())
|
||||
|
||||
def setSettings(self, settings):
|
||||
self.settings = settings
|
||||
|
||||
# ensure the setting exist
|
||||
if not self.nameInSettings in self.settings.plugins:
|
||||
self.settings.plugins[self.nameInSettings] = self.defaultValue
|
||||
|
||||
# do the same for each option in the specific options list
|
||||
for specificOption in self.specificOptions:
|
||||
nameInSettings = self.nameInSettings + "." + specificOption.mnemonic
|
||||
if not nameInSettings in self.settings.plugins:
|
||||
self.settings.plugins[nameInSettings] = specificOption.defaultValue
|
||||
|
||||
def applySetting(self, settingsWindow):
|
||||
# apply the main setting
|
||||
self.settings.plugins[self.nameInSettings] = self.uiWidget.isChecked()
|
||||
self.enabled = self.settings.plugins[self.nameInSettings]
|
||||
|
||||
# do the same for each option in the specific options list
|
||||
for specificOption in self.specificOptions:
|
||||
nameInSettings = self.nameInSettings + specificOption.mnemonic
|
||||
self.settings.plugins[nameInSettings] = specificOption.uiWidget.isChecked()
|
||||
|
||||
# disable or enable the UI in the plugins special page
|
||||
self.enableOptionsGroup()
|
||||
|
||||
def injectScripts(self, operation):
|
||||
# set the game settings
|
||||
self.settings = operation.game.settings
|
||||
|
||||
# execute the work order
|
||||
if self.scriptsWorkOrders != None:
|
||||
for workOrder in self.scriptsWorkOrders:
|
||||
workOrder.work(self.mnemonic, operation)
|
||||
|
||||
# serves for subclasses
|
||||
return self.isEnabled()
|
||||
|
||||
def injectConfiguration(self, operation):
|
||||
# set the game settings
|
||||
self.settings = operation.game.settings
|
||||
|
||||
# inject the plugin options
|
||||
if len(self.specificOptions) > 0:
|
||||
defineAllOptions = ""
|
||||
for specificOption in self.specificOptions:
|
||||
nameInSettings = self.nameInSettings + specificOption.mnemonic
|
||||
value = "true" if self.settings.plugins[nameInSettings] else "false"
|
||||
defineAllOptions += f" dcsLiberation.plugins.{self.mnemonic}.{specificOption.mnemonic} = {value} \n"
|
||||
|
||||
|
||||
lua = f"-- {self.mnemonic} plugin configuration.\n"
|
||||
lua += "\n"
|
||||
lua += "if dcsLiberation then\n"
|
||||
lua += " if not dcsLiberation.plugins then \n"
|
||||
lua += " dcsLiberation.plugins = {}\n"
|
||||
lua += " end\n"
|
||||
lua += f" dcsLiberation.plugins.{self.mnemonic} = {{}}\n"
|
||||
lua += defineAllOptions
|
||||
lua += "end"
|
||||
|
||||
operation.injectLuaTrigger(lua, f"{self.mnemonic} plugin configuration")
|
||||
|
||||
# execute the work order
|
||||
if self.configurationWorkOrders != None:
|
||||
for workOrder in self.configurationWorkOrders:
|
||||
workOrder.work(self.mnemonic, operation)
|
||||
|
||||
# serves for subclasses
|
||||
return self.isEnabled()
|
||||
|
||||
def isEnabled(self) -> bool:
|
||||
if not self.settings:
|
||||
return False
|
||||
|
||||
self.setSettings(self.settings) # create the necessary settings keys if needed
|
||||
|
||||
return self.settings != None and self.settings.plugins[self.nameInSettings]
|
||||
|
||||
def hasUI(self) -> bool:
|
||||
return not self.skipUI
|
||||
43
plugin/manager.py
Normal file
43
plugin/manager.py
Normal file
@ -0,0 +1,43 @@
|
||||
from .luaplugin import LuaPlugin
|
||||
from typing import List
|
||||
import glob
|
||||
from pathlib import Path
|
||||
import json
|
||||
import logging
|
||||
|
||||
|
||||
class LuaPluginManager():
|
||||
PLUGINS_RESOURCE_PATH = Path("resources/plugins")
|
||||
PLUGINS_LIST_FILENAME = "plugins.json"
|
||||
PLUGINS_JSON_FILENAME = "plugin.json"
|
||||
|
||||
__plugins = None
|
||||
def __init__(self):
|
||||
if not LuaPluginManager.__plugins:
|
||||
LuaPluginManager.__plugins= []
|
||||
jsonFile:Path = Path(LuaPluginManager.PLUGINS_RESOURCE_PATH, LuaPluginManager.PLUGINS_LIST_FILENAME)
|
||||
if jsonFile.exists():
|
||||
logging.info(f"Reading plugins list from {jsonFile}")
|
||||
|
||||
jsonData = json.loads(jsonFile.read_text())
|
||||
for plugin in jsonData:
|
||||
jsonPluginFolder = Path(LuaPluginManager.PLUGINS_RESOURCE_PATH, plugin)
|
||||
jsonPluginFile = Path(jsonPluginFolder, LuaPluginManager.PLUGINS_JSON_FILENAME)
|
||||
if jsonPluginFile.exists():
|
||||
logging.info(f"Reading plugin {plugin} from {jsonPluginFile}")
|
||||
plugin = LuaPlugin(jsonPluginFile)
|
||||
LuaPluginManager.__plugins.append(plugin)
|
||||
else:
|
||||
logging.error(f"Missing configuration file {jsonPluginFile} for plugin {plugin}")
|
||||
else:
|
||||
logging.error(f"Missing plugins list file {jsonFile}")
|
||||
|
||||
def getPlugins(self):
|
||||
return LuaPluginManager.__plugins
|
||||
|
||||
def getPlugin(self, pluginName):
|
||||
for plugin in LuaPluginManager.__plugins:
|
||||
if plugin.mnemonic == pluginName:
|
||||
return plugin
|
||||
|
||||
return None
|
||||
@ -1,90 +0,0 @@
|
||||
from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QPoint
|
||||
from PySide2.QtWidgets import QLabel, QDialog, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \
|
||||
QAbstractItemView, QPushButton, QGroupBox, QCheckBox, QVBoxLayout, QSpinBox
|
||||
from .base_plugin import BasePlugin
|
||||
|
||||
class VeafPlugin(BasePlugin):
|
||||
nameInUI:str = "VEAF framework"
|
||||
nameInSettings:str = "plugin.veaf"
|
||||
enabledDefaultValue:bool = False
|
||||
|
||||
#Allow spawn option
|
||||
nameInUI_allowSpawn:str = "Allow units spawn via markers and CTLD (not implemented yet)"
|
||||
nameInSettings_allowSpawn:str = "plugin.veaf.allowSpawn"
|
||||
|
||||
def setupUI(self, settingsWindow, row:int):
|
||||
# call the base method to add the plugin selection checkbox
|
||||
super().setupUI(settingsWindow, row)
|
||||
|
||||
if settingsWindow.pluginsOptionsPageLayout:
|
||||
self.optionsGroup = QGroupBox(self.nameInUI)
|
||||
optionsGroupLayout = QGridLayout();
|
||||
optionsGroupLayout.setAlignment(Qt.AlignTop)
|
||||
self.optionsGroup.setLayout(optionsGroupLayout)
|
||||
settingsWindow.pluginsOptionsPageLayout.addWidget(self.optionsGroup)
|
||||
|
||||
# allow spawn of objects
|
||||
if not self.nameInSettings_allowSpawn in self.settings.plugins:
|
||||
self.settings.plugins[self.nameInSettings_allowSpawn] = True
|
||||
|
||||
self.uiWidget_allowSpawn = QCheckBox()
|
||||
self.uiWidget_allowSpawn.setChecked(self.settings.plugins[self.nameInSettings_allowSpawn])
|
||||
self.uiWidget_allowSpawn.setEnabled(False)
|
||||
self.uiWidget_allowSpawn.toggled.connect(lambda: self.applySetting(settingsWindow))
|
||||
|
||||
optionsGroupLayout.addWidget(QLabel(self.nameInUI_allowSpawn), 0, 0)
|
||||
optionsGroupLayout.addWidget(self.uiWidget_allowSpawn, 0, 1, Qt.AlignRight)
|
||||
|
||||
# disable or enable the UI in the plugins special page
|
||||
self.enableOptionsGroup()
|
||||
|
||||
def enableOptionsGroup(self):
|
||||
pluginEnabled = self.uiWidget.isChecked()
|
||||
self.optionsGroup.setEnabled(pluginEnabled)
|
||||
|
||||
def applySetting(self, settingsWindow):
|
||||
# call the base method to apply the plugin selection checkbox value
|
||||
super().applySetting(settingsWindow)
|
||||
|
||||
# save the "allow spawn" option
|
||||
self.settings.plugins[self.nameInSettings_allowSpawn] = self.uiWidget_allowSpawn.isChecked()
|
||||
|
||||
# disable or enable the UI in the plugins special page
|
||||
self.enableOptionsGroup()
|
||||
|
||||
def injectScripts(self, operation):
|
||||
if super().injectScripts(operation):
|
||||
# bypass JTACAutoLase
|
||||
operation.bypassPluginScript("veaf", "jtacautolase")
|
||||
|
||||
# inject the required scripts
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\mist.lua", "mist")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\Moose.lua", "moose")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\CTLD.lua", "ctld")
|
||||
#operation.injectPluginScript("veaf", "src\\scripts\\NIOD.lua", "niod")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\WeatherMark.lua", "weathermark")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veaf.lua", "veaf")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\dcsUnits.lua", "dcsunits")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafAssets.lua", "veafassets")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafCarrierOperations.lua", "veafcarrieroperations")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafCasMission.lua", "veafcasmission")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafCombatMission.lua", "veafcombatmission")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafCombatZone.lua", "veafcombatzone")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafGrass.lua", "veafgrass")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafInterpreter.lua", "veafinterpreter")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafMarkers.lua", "veafmarkers")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafMove.lua", "veafmove")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafNamedPoints.lua", "veafnamedpoints")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafRadio.lua", "veafradio")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafRemote.lua", "veafremote")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafSecurity.lua", "veafsecurity")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafShortcuts.lua", "veafshortcuts")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafSpawn.lua", "veafspawn")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafTransportMission.lua", "veaftransportmission")
|
||||
operation.injectPluginScript("veaf", "src\\scripts\\veafUnits.lua", "veafunits")
|
||||
|
||||
|
||||
def injectConfiguration(self, operation):
|
||||
if super().injectConfiguration(operation):
|
||||
operation.injectPluginScript("veaf", "src\\config\\missionConfig.lua", "veaf-config")
|
||||
|
||||
@ -11,7 +11,7 @@ from game.game import Game
|
||||
from game.infos.information import Information
|
||||
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
||||
from qt_ui.windows.finances.QFinancesMenu import QHorizontalSeparationLine
|
||||
from plugin import BasePlugin, INSTALLED_PLUGINS
|
||||
from plugin import LuaPluginManager
|
||||
|
||||
class QSettingsWindow(QDialog):
|
||||
|
||||
@ -19,6 +19,8 @@ class QSettingsWindow(QDialog):
|
||||
super(QSettingsWindow, self).__init__()
|
||||
|
||||
self.game = game
|
||||
self.pluginsPage = None
|
||||
self.pluginsOptionsPage = None
|
||||
|
||||
self.setModal(True)
|
||||
self.setWindowTitle("Settings")
|
||||
@ -37,53 +39,53 @@ class QSettingsWindow(QDialog):
|
||||
|
||||
self.categoryModel = QStandardItemModel(self.categoryList)
|
||||
|
||||
self.categoryList.setIconSize(QSize(32, 32))
|
||||
|
||||
self.initDifficultyLayout()
|
||||
difficulty = QStandardItem("Difficulty")
|
||||
difficulty.setIcon(CONST.ICONS["Missile"])
|
||||
difficulty.setEditable(False)
|
||||
difficulty.setSelectable(True)
|
||||
self.categoryModel.appendRow(difficulty)
|
||||
self.right_layout.addWidget(self.difficultyPage)
|
||||
|
||||
self.initGeneratorLayout()
|
||||
generator = QStandardItem("Mission Generator")
|
||||
generator.setIcon(CONST.ICONS["Generator"])
|
||||
generator.setEditable(False)
|
||||
generator.setSelectable(True)
|
||||
self.categoryModel.appendRow(generator)
|
||||
self.right_layout.addWidget(self.generatorPage)
|
||||
|
||||
self.initCheatLayout()
|
||||
cheat = QStandardItem("Cheat Menu")
|
||||
cheat.setIcon(CONST.ICONS["Cheat"])
|
||||
cheat.setEditable(False)
|
||||
cheat.setSelectable(True)
|
||||
|
||||
plugins = QStandardItem("LUA Plugins")
|
||||
plugins.setIcon(CONST.ICONS["Plugins"])
|
||||
plugins.setEditable(False)
|
||||
plugins.setSelectable(True)
|
||||
|
||||
pluginsOptions = QStandardItem("LUA Plugins Options")
|
||||
pluginsOptions.setIcon(CONST.ICONS["PluginsOptions"])
|
||||
pluginsOptions.setEditable(False)
|
||||
pluginsOptions.setSelectable(True)
|
||||
|
||||
self.categoryList.setIconSize(QSize(32, 32))
|
||||
self.categoryModel.appendRow(difficulty)
|
||||
self.categoryModel.appendRow(generator)
|
||||
self.categoryModel.appendRow(cheat)
|
||||
self.categoryModel.appendRow(plugins)
|
||||
self.categoryModel.appendRow(pluginsOptions)
|
||||
self.right_layout.addWidget(self.cheatPage)
|
||||
|
||||
self.initPluginsLayout()
|
||||
if self.pluginsPage:
|
||||
plugins = QStandardItem("LUA Plugins")
|
||||
plugins.setIcon(CONST.ICONS["Plugins"])
|
||||
plugins.setEditable(False)
|
||||
plugins.setSelectable(True)
|
||||
self.categoryModel.appendRow(plugins)
|
||||
self.right_layout.addWidget(self.pluginsPage)
|
||||
if self.pluginsOptionsPage:
|
||||
pluginsOptions = QStandardItem("LUA Plugins Options")
|
||||
pluginsOptions.setIcon(CONST.ICONS["PluginsOptions"])
|
||||
pluginsOptions.setEditable(False)
|
||||
pluginsOptions.setSelectable(True)
|
||||
self.categoryModel.appendRow(pluginsOptions)
|
||||
self.right_layout.addWidget(self.pluginsOptionsPage)
|
||||
|
||||
self.categoryList.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||
self.categoryList.setModel(self.categoryModel)
|
||||
self.categoryList.selectionModel().setCurrentIndex(self.categoryList.indexAt(QPoint(1,1)), QItemSelectionModel.Select)
|
||||
self.categoryList.selectionModel().selectionChanged.connect(self.onSelectionChanged)
|
||||
|
||||
self.initDifficultyLayout()
|
||||
self.initGeneratorLayout()
|
||||
self.initCheatLayout()
|
||||
self.initPluginsLayout()
|
||||
|
||||
self.right_layout.addWidget(self.difficultyPage)
|
||||
self.right_layout.addWidget(self.generatorPage)
|
||||
self.right_layout.addWidget(self.cheatPage)
|
||||
self.right_layout.addWidget(self.pluginsPage)
|
||||
self.right_layout.addWidget(self.pluginsOptionsPage)
|
||||
|
||||
self.layout.addWidget(self.categoryList, 0, 0, 1, 1)
|
||||
self.layout.addLayout(self.right_layout, 0, 1, 5, 1)
|
||||
@ -281,28 +283,32 @@ class QSettingsWindow(QDialog):
|
||||
self.cheatLayout.addWidget(self.moneyCheatBox, 0, 0)
|
||||
|
||||
def initPluginsLayout(self):
|
||||
self.pluginsOptionsPage = QWidget()
|
||||
self.pluginsOptionsPageLayout = QVBoxLayout()
|
||||
self.pluginsOptionsPageLayout.setAlignment(Qt.AlignTop)
|
||||
self.pluginsOptionsPage.setLayout(self.pluginsOptionsPageLayout)
|
||||
|
||||
self.pluginsPage = QWidget()
|
||||
self.pluginsPageLayout = QVBoxLayout()
|
||||
self.pluginsPageLayout.setAlignment(Qt.AlignTop)
|
||||
self.pluginsPage.setLayout(self.pluginsPageLayout)
|
||||
|
||||
self.pluginsGroup = QGroupBox("Plugins")
|
||||
self.pluginsGroupLayout = QGridLayout();
|
||||
self.pluginsGroupLayout.setAlignment(Qt.AlignTop)
|
||||
self.pluginsGroup.setLayout(self.pluginsGroupLayout)
|
||||
|
||||
uiPrepared = False
|
||||
row:int = 0
|
||||
for pluginName in INSTALLED_PLUGINS:
|
||||
plugin = INSTALLED_PLUGINS[pluginName]
|
||||
plugin.setupUI(self, row)
|
||||
row = row + 1
|
||||
for plugin in LuaPluginManager().getPlugins():
|
||||
if plugin.hasUI():
|
||||
if not uiPrepared:
|
||||
uiPrepared = True
|
||||
|
||||
self.pluginsPageLayout.addWidget(self.pluginsGroup)
|
||||
self.pluginsOptionsPage = QWidget()
|
||||
self.pluginsOptionsPageLayout = QVBoxLayout()
|
||||
self.pluginsOptionsPageLayout.setAlignment(Qt.AlignTop)
|
||||
self.pluginsOptionsPage.setLayout(self.pluginsOptionsPageLayout)
|
||||
|
||||
self.pluginsPage = QWidget()
|
||||
self.pluginsPageLayout = QVBoxLayout()
|
||||
self.pluginsPageLayout.setAlignment(Qt.AlignTop)
|
||||
self.pluginsPage.setLayout(self.pluginsPageLayout)
|
||||
|
||||
self.pluginsGroup = QGroupBox("Plugins")
|
||||
self.pluginsGroupLayout = QGridLayout();
|
||||
self.pluginsGroupLayout.setAlignment(Qt.AlignTop)
|
||||
self.pluginsGroup.setLayout(self.pluginsGroupLayout)
|
||||
|
||||
self.pluginsPageLayout.addWidget(self.pluginsGroup)
|
||||
|
||||
plugin.setupUI(self, row)
|
||||
row = row + 1
|
||||
|
||||
def cheatLambda(self, amount):
|
||||
return lambda: self.cheatMoney(amount)
|
||||
|
||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
84
resources/plugins/_doc/plugins_readme.md
Normal file
84
resources/plugins/_doc/plugins_readme.md
Normal file
@ -0,0 +1,84 @@
|
||||
# LUA Plugin system
|
||||
|
||||
This plugin system was made for injecting LUA scripts in dcs-liberation missions.
|
||||
|
||||
The resources for the plugins are stored in the `resources/plugins` folder ; each plugin has its own folder.
|
||||
|
||||
## How does the system work ?
|
||||
|
||||
The application first reads the `resources/plugins/plugins.json` file to get a list of plugins to load, in order.
|
||||
Each entry in this list should correspond to a subfolder of the `resources/plugins` directory, where a `plugin.json` file exists.
|
||||
This file is the description of the plugin.
|
||||
|
||||
### plugin.json
|
||||
|
||||
The *base* and *jtacautolase* plugins both are included in the standard dcs-liberation distribution.
|
||||
You can check their respective `plugin.json` files to understand how they work.
|
||||
Here's a quick rundown of the file's components :
|
||||
|
||||
- `mnemonic` : the short, technical name of the plugin. It's the name of the folder, and the name of the plugin in the application's settings
|
||||
- `skipUI` : if *true*, this plugin will not appear in the plugins selection user interface. Useful to force a plugin ON or OFF (see the *base* plugin)
|
||||
- `nameInUI` : the title of the plugin as it will appear in the plugins selection user interface.
|
||||
- `defaultValue` : the selection value of the plugin, when first installed ; if true, plugin is selected.
|
||||
- `specificOptions` : a list of specific plugin options
|
||||
- `nameInUI` : the title of the option as it will appear in the plugins specific options user interface.
|
||||
- `mnemonic` : the short, technical name of the option. It's the name of the LUA variable passed to the configuration script, and the name of the option in the application's settings
|
||||
- `defaultValue` : the selection value of the option, when first installed ; if true, option is selected.
|
||||
- `scriptsWorkOrders` : a list of work orders that can be used to load or disable loading a specific LUA script
|
||||
- `file` : the name of the LUA file in the plugin folder.
|
||||
- `mnemonic` : the technical name of the LUA component. The filename may be more precise than needed (e.g. include a version number) ; this is used to load each file only once, and also to disable loading a file
|
||||
- `disable` : if true, the script will be disabled instead of loaded
|
||||
- `configurationWorkOrders` : a list of work orders that can be used to load a configuration LUA script (same description as above)
|
||||
|
||||
## Standard plugins
|
||||
|
||||
### The *base* plugin
|
||||
|
||||
The *base* plugin contains the scripts that are going to be injected in every dcs-liberation missions.
|
||||
It is mandatory.
|
||||
|
||||
### The *JTACAutolase* plugin
|
||||
|
||||
This plugin replaces the vanilla JTAC functionality in dcs-liberation.
|
||||
|
||||
### The *VEAF framework* plugin
|
||||
|
||||
When enabled, this plugin will inject and configure the VEAF Framework scripts in the mission.
|
||||
|
||||
These scripts add a lot of runtime functionalities :
|
||||
|
||||
- spawning of units and groups (and portable TACANs)
|
||||
- air-to-ground missions
|
||||
- air-to-air missions
|
||||
- transport missions
|
||||
- carrier operations (not Moose)
|
||||
- tanker move
|
||||
- weather and ATC
|
||||
- shelling a zone, lighting it up
|
||||
- managing assets (tankers, awacs, aircraft carriers) : getting info, state, respawning them if needed
|
||||
- managing named points (position, info, ATC)
|
||||
- managing a dynamic radio menu
|
||||
- managing remote calls to the mission through NIOD (RPC) and SLMOD (LUA sockets)
|
||||
- managing security (not allowing everyone to do every action)
|
||||
- define groups templates
|
||||
|
||||
You can find the *VEAF Framework* plugin [on GitHub](https://github.com/VEAF/dcs-liberation-veaf-framework/releases)
|
||||
For more information, please visit the [VEAF Framework documentation site](https://veaf.github.io/VEAF-Mission-Creation-Tools/) (work in progress)
|
||||
|
||||
## Custom plugins
|
||||
|
||||
The easiest way to create a custom plugin is to copy an existing plugin, and modify the files.
|
||||
|
||||
## New settings pages
|
||||
|
||||

|
||||
|
||||
Custom plugins can be enabled or disabled in the new *LUA Plugins* settings page.
|
||||
|
||||

|
||||
|
||||
For plugins which expose specific options (such as "use smoke" for the *JTACAutoLase* plugin), the *LUA Plugins Options* settings page lists these options.
|
||||
|
||||

|
||||
|
||||
|
||||
22
resources/plugins/base/plugin.json
Normal file
22
resources/plugins/base/plugin.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"mnemonic": "base",
|
||||
"skipUI": true,
|
||||
"nameInUI": "",
|
||||
"defaultValue": true,
|
||||
"specificOptions": [],
|
||||
"scriptsWorkOrders": [
|
||||
{
|
||||
"file": "mist_4_3_74.lua",
|
||||
"mnemonic": "mist"
|
||||
},
|
||||
{
|
||||
"file": "json.lua",
|
||||
"mnemonic": "json"
|
||||
},
|
||||
{
|
||||
"file": "dcs_liberation.lua",
|
||||
"mnemonic": "liberation"
|
||||
}
|
||||
],
|
||||
"configurationWorkOrders": []
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
# this is a list of lua scripts that will be injected in the mission, in the same order
|
||||
mist.lua
|
||||
Moose.lua
|
||||
CTLD.lua
|
||||
NIOD.lua
|
||||
WeatherMark.lua
|
||||
veaf.lua
|
||||
dcsUnits.lua
|
||||
# JTACAutoLase is an empty file, only there to disable loading the official script (already included in CTLD)
|
||||
JTACAutoLase.lua
|
||||
veafAssets.lua
|
||||
veafCarrierOperations.lua
|
||||
veafCarrierOperations2.lua
|
||||
veafCasMission.lua
|
||||
veafCombatMission.lua
|
||||
veafCombatZone.lua
|
||||
veafGrass.lua
|
||||
veafInterpreter.lua
|
||||
veafMarkers.lua
|
||||
veafMove.lua
|
||||
veafNamedPoints.lua
|
||||
veafRadio.lua
|
||||
veafRemote.lua
|
||||
veafSecurity.lua
|
||||
veafShortcuts.lua
|
||||
veafSpawn.lua
|
||||
veafTransportMission.lua
|
||||
veafUnits.lua
|
||||
missionConfig.lua
|
||||
@ -1,58 +0,0 @@
|
||||
# LUA Plugin system
|
||||
|
||||
This plugin system was made for injecting LUA scripts in dcs-liberation missions.
|
||||
|
||||
The resources for the plugins are stored in the `resources/plugins` folder ; each plugin has its own folder.
|
||||
|
||||
## Standard plugins
|
||||
|
||||
### The *base* plugin
|
||||
|
||||
The *base* plugin contains the scripts that are going to be injected in every dcs-liberation missions.
|
||||
It is mandatory.
|
||||
|
||||
### The *JTACAutolase* plugin
|
||||
|
||||
This plugin replaces the vanilla JTAC functionality in dcs-liberation.
|
||||
|
||||
### The *VEAF framework* plugin
|
||||
|
||||
When enabled, this plugin will inject and configure the VEAF Framework scripts in the mission.
|
||||
|
||||
These scripts add a lot of runtime functionalities :
|
||||
|
||||
- spawning of units and groups (and portable TACANs)
|
||||
- air-to-ground missions
|
||||
- air-to-air missions
|
||||
- transport missions
|
||||
- carrier operations (not Moose)
|
||||
- tanker move
|
||||
- weather and ATC
|
||||
- shelling a zone, lighting it up
|
||||
- managing assets (tankers, awacs, aircraft carriers) : getting info, state, respawning them if needed
|
||||
- managing named points (position, info, ATC)
|
||||
- managing a dynamic radio menu
|
||||
- managing remote calls to the mission through NIOD (RPC) and SLMOD (LUA sockets)
|
||||
- managing security (not allowing everyone to do every action)
|
||||
- define groups templates
|
||||
|
||||
For more information, please visit the [VEAF Framework documentation site](https://veaf.github.io/VEAF-Mission-Creation-Tools/) (work in progress)
|
||||
|
||||
## Custom plugins
|
||||
|
||||
Custom scripts can also be injected by dropping them in the `resources/plugins/custom` folder, and writing a `__plugins.lst` file listing them in order.
|
||||
See the `__plugins.lst.sample` file for an example.
|
||||
|
||||
## New settings pages
|
||||
|
||||

|
||||
|
||||
Custom plugins can be enabled or disabled in the new *LUA Plugins* settings page.
|
||||
|
||||

|
||||
|
||||
For plugins which expose specific options (such as "use smoke" for the *JTACAutoLase* plugin), the *LUA Plugins Options* settings page lists these options.
|
||||
|
||||

|
||||
|
||||
|
||||
38
resources/plugins/jtacautolase/jtacautolase-config.lua
Normal file
38
resources/plugins/jtacautolase/jtacautolase-config.lua
Normal file
@ -0,0 +1,38 @@
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- configuration file for the JTAC Autolase framework
|
||||
--
|
||||
-- This configuration is tailored for a mission generated by DCS Liberation
|
||||
-- see https://github.com/Khopa/dcs_liberation
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- JTACAutolase plugin - configuration
|
||||
env.info("DCSLiberation|JTACAutolase plugin - configuration")
|
||||
|
||||
if dcsLiberation then
|
||||
veaf.logTrace("dcsLiberation")
|
||||
|
||||
-- specific options
|
||||
local smoke = false
|
||||
|
||||
-- retrieve specific options values
|
||||
if dcsLiberation.plugins then
|
||||
veaf.logTrace("dcsLiberation.plugins")
|
||||
|
||||
if dcsLiberation.plugins.jtacautolase then
|
||||
veaf.logTrace("dcsLiberation.plugins.jtacautolase")
|
||||
veaf.logTrace(string.format("dcsLiberation.plugins.jtacautolase.smoke=%s",veaf.p(dcsLiberation.plugins.jtacautolase.smoke)))
|
||||
|
||||
smoke = dcsLiberation.plugins.jtacautolase.smoke
|
||||
end
|
||||
end
|
||||
|
||||
veaf.logTrace(string.format("smoke=%s",veaf.p(smoke)))
|
||||
|
||||
-- actual configuration code
|
||||
for _, jtac in pairs(dcsLiberation.JTACs) do
|
||||
if dcsLiberation.JTACAutoLase then
|
||||
dcsLiberation.JTACAutoLase(jtac.dcsUnit, jtac.code, smoke, 'vehicle')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
6822
resources/plugins/jtacautolase/mist_4_3_74.lua
Normal file
6822
resources/plugins/jtacautolase/mist_4_3_74.lua
Normal file
File diff suppressed because it is too large
Load Diff
28
resources/plugins/jtacautolase/plugin.json
Normal file
28
resources/plugins/jtacautolase/plugin.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"mnemonic": "jtacautolase",
|
||||
"nameInUI": "JTAC Autolase",
|
||||
"defaultValue": true,
|
||||
"specificOptions": [
|
||||
{
|
||||
"nameInUI": "Use smoke",
|
||||
"mnemonic": "smoke",
|
||||
"defaultValue": true
|
||||
}
|
||||
],
|
||||
"scriptsWorkOrders": [
|
||||
{
|
||||
"file": "mist_4_3_74.lua",
|
||||
"mnemonic": "mist"
|
||||
},
|
||||
{
|
||||
"file": "JTACAutoLase.lua",
|
||||
"mnemonic": "jtacautolase-script"
|
||||
}
|
||||
],
|
||||
"configurationWorkOrders": [
|
||||
{
|
||||
"file": "configuration.lua",
|
||||
"mnemonic": "jtacautolase-config"
|
||||
}
|
||||
]
|
||||
}
|
||||
5
resources/plugins/plugins.json
Normal file
5
resources/plugins/plugins.json
Normal file
@ -0,0 +1,5 @@
|
||||
[
|
||||
"veaf",
|
||||
"jtacautolase",
|
||||
"base"
|
||||
]
|
||||
@ -1 +0,0 @@
|
||||
Subproject commit 219cdffef087660fe448a41e1f187c4856e9d80f
|
||||
Loading…
x
Reference in New Issue
Block a user