local base = _G module('MissionResourcesDialog') local require = base.require local math = base.math local pairs = base.pairs local ipairs = base.ipairs local table = base.table local tonumber = base.tonumber local tostring = base.tostring local DialogLoader = require("DialogLoader") local ListBoxItem = require('ListBoxItem') local GridHeaderCell = require('GridHeaderCell') local Menu = require('Menu') local MenuItem = require('MenuItem') local Picture = require('Picture') local payloadUtils = require('me_payloadutils'); local ConfigHelper = require('ConfigHelper') local DB = require('me_db_api') local gettext = require('i_18n') _ = function(p) return gettext.translate(p); end; local cdata = { aircraftName = _('A-10C'); chaff = _('CHAFF'); flare = _('FLARE'); fuel = _('FUEL'); toWeight = _('TO weight, %'); toWeightMax = _('TO weight max'); gunAmmoType = _('GUN AMMO TYPE'); gunAmmo = _('GUN AMMO'); toWeightCurrent = _('TO weight current'); payload = _('Payload'), empty = _("EMPTY"), cancel = _("CANCEL"), ok = _("OK"), totalWeight = _("TOTAL WEIGHT"), maximumWeight = _("MAXIMUM WEIGHT"), selectLoadout = _("SELECT LOADOUT:"), kg = _("KG"), clear = _("Clear"), available = _('(avail: %5d) : %s'), } unitPayloads = {}; function createColumns(currentUnitType) local pylonsCount = payloadUtils.getPylonsCount(currentUnitType) local leftColumnWidth = 0 local x,y,w,h = grdPayloads:getBounds() w = 2 * leftColumnWidth + 3 + pylonsCount * (1 + payloadUtils.columnWidth) grdPayloads:setBounds(x, y, w, h); grdPayloads:insertColumn(leftColumnWidth, nil, 0) for i = 1, pylonsCount do local columnHeader = GridHeaderCell.new(tostring(i), true) grdPayloads:insertColumn(payloadUtils.columnWidth, columnHeader, 1) end end function createRows(currentUnitType) local row = 0 grdPayloads:insertRow(payloadUtils.rowHeight, row) grdPayloads:setCell(0, row, nil) local columnCount = grdPayloads:getColumnCount() for pylonNumber, pylon in pairs(currentPayload.pylons) do local column = columnCount - pylonNumber; local container = nil if pylon.count > 0 then container = payloadUtils.createPylonCell(pylon.clsid, column, row, grdPayloads, pylon.count) end grdPayloads:setCell(column, row, container) end; end function updateGrid(unitType) currentUnitType = unitType grdPayloads:clear() createColumns(currentUnitType) createRows(currentUnitType) updateWeight(); end function create() window = DialogLoader.spawnDialogFromFile('./Scripts/UI/MissionResourcesDialog.dlg', cdata) window:centerWindow() stcImage = window.stcImage stcImageSkin = stcImage:getSkin() stcImageSkinPicture = stcImageSkin.skinData.states.released[1].picture txtFlare = window.txtFlare txtChaff = window.txtChaff txtGunAmmo = window.txtGunAmmo stcGunAmmoType = window.stcGunAmmoType txtFuel = window.txtFuel sldrFlare = window.sldrFlare sldrChaff = window.sldrChaff check_chaff_flare_slots = function (user_enter_flare) local ChaffChargeSize = 1 local FlareChargeSize = 1 if currentUnit.ChaffChargeSize ~= nil then ChaffChargeSize = currentUnit.ChaffChargeSize end if currentUnit.FlareChargeSize ~= nil then FlareChargeSize = currentUnit.FlareChargeSize end local chaffSlots = sldrChaff:getValue() * ChaffChargeSize local flareSlots = sldrFlare:getValue() * FlareChargeSize if currentUnit.SingleChargeTotal < chaffSlots + flareSlots then if user_enter_flare then local chaff = (currentUnit.SingleChargeTotal - flareSlots) / ChaffChargeSize sldrChaff:setValue(chaff) else local flare = (currentUnit.SingleChargeTotal - chaffSlots) / FlareChargeSize sldrFlare:setValue(flare) end end onUpdateWeight() return end sldrFlare.onChange = function () check_chaff_flare_slots(true) end sldrChaff.onChange = function () check_chaff_flare_slots(false) end sldrGunAmmo = window.sldrGunAmmo sldrGunAmmo.onChange = onUpdateWeight cmbGunAmmoType = window.cmbGunAmmoType sldrFuel = window.sldrFuel sldrFuel.onChange = onUpdateWeight txtFlareCurrent = window.txtFlareCurrent txtChaffCurrent = window.txtChaffCurrent txtGunAmmoCurrent = window.txtGunAmmoCurrent txtFuelCurrent = window.txtFuelCurrent labelWeightCurrent = window.labelWeightCurrent labelWeightMax = window.labelWeightMax stcToWeightCurrentValue = window.stcToWeightCurrentValue stcToWeightMaxValue = window.stcToWeightMaxValue txtUnits = window.txtUnits txtPreset = window.txtPreset listBoxPreset = window.listBoxPreset btnOk = window.btnOk btnOk.onChange = onButtonOk btnCancel = window.btnCancel btnCancel.onChange = onButtonCancel grdPayloads = window.grdPayloads function grdPayloads:onMouseDown(x, y, button) onPylonMouseDown(x, y, button) end unitPayloads = base.dofile(ConfigHelper.getConfigReadPath('unitPayloads.lua')) or {} payloadUtils.init(); gridMenu = Menu.new() gridMenu.onChange = menuOnChange; submenus = {}; end; function onSpinGunAmmo(self, value) updateWeight(); end; function onUpdateWeight(self, value) updateWeight(); end; function onButtonOk(self) if not currentUnit then return end local ammo_type = 0 if currentUnit.ammo_type then local res = cmbGunAmmoType:getSelectedItem(); if res then ammo_type = res.index end end; local outData = { numChaff = tonumber(sldrChaff:getValue()); numFlare = tonumber(sldrFlare:getValue()); currentAmmo = tonumber(sldrGunAmmo:getValue()); ammoType = ammo_type; fuel = sldrFuel:getValue()/100*currentUnit.MaxFuelWeight; pylons = {}; } for i, pylon in pairs(currentPayload.pylons) do outData.pylons[i] = pylon.clsid; end; requestPayloads(outData); show(false); end; function onButtonCancel(self) show(false); end; function show(state) window:setVisible(state); if state == false then showWindow(false); -- C call end; end; function isVisible() return window:isVisible(); end; function get_max_chaff() if currentUnit and currentUnit.ChaffDefault and currentUnit.ChaffChargeSize then return currentUnit.ChaffDefault * currentUnit.ChaffChargeSize else return 0 end end function get_max_flare() if currentUnit and currentUnit.FlareDefault and currentUnit.FlareChargeSize then return currentUnit.FlareDefault * currentUnit.FlareChargeSize else return 0 end end function updatePayloadPresets(currentUnitType) listBoxPreset:clear() listBoxPreset:setVisible(true) listBoxPreset.onChange = function(self,item) --clear all pylons; for i,o in pairs(currentPayload.pylons) do o.clsid = 0 o.count = 0 end if item and item.preset_link then for i,o in pairs(item.preset_link.pylons) do local pylon = currentPayload.pylons[o.num] pylon.clsid = o.launcherCLSID pylon.count = 1; end end updateGrid(currentUnitType); end local payloads = payloadUtils.getUnitPayloads(currentUnitType, unitPayloads) local empty = ListBoxItem.new(cdata.empty); listBoxPreset:insertItem(empty); for i,o in pairs(payloads) do if o.pylons and #o.pylons > 0 then local comboItem = ListBoxItem.new(o.name); comboItem.preset_link = o; listBoxPreset:insertItem(comboItem); end end end function update(params) currentPayload = params; currentUnit = DB.unit_by_type[params.unitType]; stcImageSkinPicture.file = currentUnit.Picture stcImage:setSkin(stcImageSkin) m_chaff = get_max_chaff() m_flare = get_max_flare() if m_chaff > 0 then txtChaff:setVisible(true) txtChaffCurrent:setVisible(true) sldrChaff:setVisible(true) sldrChaff:setRange(0, m_chaff); else txtChaff:setVisible(false) txtChaffCurrent:setVisible(false) sldrChaff:setVisible(false) sldrChaff:setRange(0,100); end if m_flare > 0 then txtFlare:setVisible(true) txtFlareCurrent:setVisible(true) sldrFlare:setVisible(true) sldrFlare:setRange(0, m_flare); else txtFlare:setVisible(false) txtFlareCurrent:setVisible(false) sldrFlare:setVisible(false) sldrFlare:setRange(0,100); end sldrChaff:setValue(params.numChaff); sldrFlare:setValue(params.numFlare); sldrChaff:setStep(currentUnit.CMDS_Incrementation or 1) sldrFlare:setStep(currentUnit.CMDS_Incrementation or 1) sldrGunAmmo:setRange(0, 100); if params.maximumAmmo > 0 then sldrGunAmmo:setValue(math.ceil(params.currentAmmo/params.maximumAmmo*100)); sldrGunAmmo:setVisible(true) txtGunAmmo:setVisible(true); txtGunAmmoCurrent:setVisible(true); if currentUnit and currentUnit.ammo_type then cmbGunAmmoType:setVisible(true); stcGunAmmoType:setVisible(true); cmbGunAmmoType:clear(); local selectedItem; local ammoType = params.ammoType or 0 for i = 1, #currentUnit.ammo_type do local comboItem = ListBoxItem.new(currentUnit.ammo_type[i]); comboItem.index = i - 1; cmbGunAmmoType:insertItem(comboItem); if comboItem.index == ammoType then selectedItem = comboItem; end; end; cmbGunAmmoType:selectItem(selectedItem); else cmbGunAmmoType:setVisible(false); stcGunAmmoType:setVisible(false); end; else sldrGunAmmo:setValue(0); sldrGunAmmo:setVisible(false); txtGunAmmo:setVisible(false); txtGunAmmoCurrent:setVisible(false); cmbGunAmmoType:setVisible(false); stcGunAmmoType:setVisible(false); end stcToWeightMaxValue:setText(math.ceil(params.fullWeight/tonumber(currentUnit.MaxTakeOffWeight)*100)); stcToWeightCurrentValue:setText(params.fullWeight); local v = math.ceil(params.numFuel/currentUnit.MaxFuelWeight*100); sldrFuel:setValue(v); updateGrid(params.unitType); updatePayloadPresets(params.unitType); end; function getSubmenu(i, submenuOnChange) submenus[i] = submenus[i] or Menu.new(); if submenuOnChange then submenus[i].onChange = function(self, item) submenuOnChange(item); end; end; return submenus[i]; end; function menuOnChange( self, item) local pylon = currentPayload.pylons[item.pylonNumber] or {}; if item.is_remove then pylon.clsid = 0; pylon.count = 0; currentPayload.pylons[item.pylonNumber] = pylon; end; updateGrid(currentUnitType); end function submenuOnChange(item) if (currentPayload ~= nil) and (currentPayload.pylons ~= nil) then local pylon = currentPayload.pylons[item.pylonNumber] or {}; if item.launcher then pylon.clsid = item.launcher.clsid; pylon.count = 1; else pylon.clsid = 0; pylon.count = 0; end; currentPayload.pylons[item.pylonNumber] = pylon; updateGrid(currentUnitType); end; end function updatePylonMenu(currentUnitType, pylonNumber, menuOnChange, submenuOnChange) local pylon = currentUnit.Pylons[pylonNumber]; local launchersByCLSID = {}; local launcherCategories = {}; local categoryNames = {}; for k,launcher in pairs(pylon.Launchers) do local numWeapons = requestWeaponCount(launcher.CLSID); local category = payloadUtils.launcherCategiries__[launcher.CLSID]; if category ~= nil then launchersByCLSID[launcher.CLSID] = numWeapons; if launcherCategories[category] == nil then launcherCategories[category] = {}; table.insert(categoryNames, category); end; table.insert(launcherCategories[category], {clsid = launcher.CLSID, count = numWeapons, name = base.get_weapon_display_name_by_clsid(launcher.CLSID)}); end; end; table.sort(categoryNames); gridMenu:clear() -- для каждой категории создаем подменю local counter = 1; for i, categoryName in pairs(categoryNames) do local launchers = launcherCategories[categoryName]; table.sort(launchers, function(op1, op2) return op1.name < op2.name; end) local submenu = getSubmenu(counter, submenuOnChange) counter = counter + 1; submenu:clear() for i, launcher in ipairs(launchers) do local submenuItem = nil if launcher.count > 1000000 then --infinite submenuItem = MenuItem.new(launcher.name) else submenuItem = MenuItem.new(base.string.format(cdata.available, launcher.count, launcher.name)) end submenuItem.pylonNumber = pylonNumber; submenuItem.launcher = launcher; submenu:insertItem(submenuItem) end; local menuItem = MenuItem.SubItem.new(categoryName, submenu) gridMenu:insertItem(menuItem) end local separator = MenuItem.Separator.new() gridMenu:insertItem(separator) local menuItem = MenuItem.new(cdata.clear) menuItem.pylonNumber = pylonNumber; menuItem.is_remove = true; gridMenu:insertItem(menuItem) return gridMenu end function onPylonMouseDown(x, y, button) if 3 == button then local col, row = grdPayloads:getMouseCursorColumnRow(x, y) if -1 < col and -1 < row then local columns = grdPayloads:getColumnCount() local pylonNumber = columns - col -- формируем меню updatePylonMenu(currentUnitType, pylonNumber, menuOnChange, submenuOnChange)-- позиционируем меню local _tmp, _tmp1, w, h = gridMenu:getBounds() gridMenu:setBounds(x, y, w, h) gridMenu:setVisible(true) end; end end function updateWeight() local ammo_weight_max = 900 local max_to_weight = 18000 local max_fuel_weight = 6000 local empty_weight = 6000 if currentUnit then ammo_weight_max = currentUnit.AmmoWeight max_to_weight = currentUnit.MaxTakeOffWeight max_fuel_weight = currentUnit.MaxFuelWeight empty_weight = currentUnit.EmptyWeight end local payloadsWeight = 0; if currentPayload and currentPayload.pylons ~= nil then for i, pylon in pairs(currentPayload.pylons) do local launcher = DB.db.Weapons.ByCLSID[pylon.clsid]; if launcher then payloadsWeight = payloadsWeight + launcher.Weight; end; end; end; local ammoWeight = ammo_weight_max*sldrGunAmmo:getValue()/100; local fuel = sldrFuel:getValue()*max_fuel_weight/100; txtFlareCurrent:setText(sldrFlare:getValue()) txtChaffCurrent:setText(sldrChaff:getValue()) txtGunAmmoCurrent:setText(sldrGunAmmo:getValue() .. '\%') txtFuelCurrent:setText(sldrFuel:getValue() .. '\%') total = empty_weight + payloadsWeight + ammoWeight + fuel; local maxTOWeight = tonumber(max_to_weight); stcToWeightCurrentValue:setText(math.ceil(total)); stcToWeightMaxValue:setText(max_to_weight); end;