From 68714793dcfdaf5f2e02e3f3f09d430fc9955201 Mon Sep 17 00:00:00 2001 From: David Schwietering Date: Mon, 16 Dec 2024 15:52:05 +0100 Subject: [PATCH 1/3] Added file system load check and custom field gui improvements --- Courseplay.lua | 5 +- config/MasterTranslations.xml | 4 ++ modDesc.xml | 3 +- scripts/courseManager/FileSystem.lua | 11 +++- scripts/editor/CourseEditor.lua | 37 +++++++----- scripts/field/CustomField.lua | 53 ++++++++++------- scripts/field/CustomFieldManager.lua | 52 ++++++++++------- scripts/gui/CpInGameMenu.lua | 34 ++++++++++- ...pAIHotspots.lua => CustomFieldHotspot.lua} | 53 +++++++++-------- scripts/gui/pages/CpCourseGeneratorFrame.lua | 57 +++++++++++++++++-- scripts/gui/pages/CpCourseManagerFrame.lua | 16 +++++- scripts/gui/pages/CpGlobalSettingsFrame.lua | 12 ++++ scripts/gui/pages/CpHelpFrame.lua | 12 ++++ scripts/gui/pages/CpVehicleSettingsFrame.lua | 12 ++++ scripts/specializations/CpCourseManager.lua | 17 +++--- scripts/test/CourseManagerTest.lua | 2 +- 16 files changed, 278 insertions(+), 102 deletions(-) rename scripts/gui/{CpAIHotspots.lua => CustomFieldHotspot.lua} (55%) diff --git a/Courseplay.lua b/Courseplay.lua index 2e4af057..7e220d65 100644 --- a/Courseplay.lua +++ b/Courseplay.lua @@ -28,6 +28,7 @@ function Courseplay:registerXmlSchema() self.globalSettings:registerXmlSchema(self.xmlSchema, self.xmlKey) CpBaseHud.registerXmlSchema(self.xmlSchema, self.xmlKey) CpHudInfoTexts.registerXmlSchema(self.xmlSchema, self.xmlKey) + CpInGameMenu.registerXmlSchema(self.xmlSchema, self.xmlKey) end --- Loads data not tied to a savegame. @@ -36,6 +37,7 @@ function Courseplay:loadUserSettings() if xmlFile then self:showUserInformation(xmlFile, self.baseXmlKey) self.globalSettings:loadFromXMLFile(xmlFile, self.xmlKey) + g_cpInGameMenu:loadFromXMLFile(xmlFile, self.xmlKey) CpBaseHud.loadFromXmlFile(xmlFile, self.xmlKey) CpHudInfoTexts.loadFromXmlFile(xmlFile, self.xmlKey) xmlFile:save() @@ -55,6 +57,7 @@ function Courseplay:saveUserSettings() if self.currentVersion then xmlFile:setValue(self.baseXmlKey.."#lastVersion", self.currentVersion) end + g_cpInGameMenu:saveToXMLFile(xmlFile, g_Courseplay.xmlKey) xmlFile:save() xmlFile:delete() end @@ -94,7 +97,6 @@ end function Courseplay:loadMap(filename) self.globalSettings = CpGlobalSettings() self:registerXmlSchema() - self:loadUserSettings() --- Savegame infos here CpUtil.info("Map loaded: %s, Savegame name: %s(%d)", g_currentMission.missionInfo.mapId, @@ -102,6 +104,7 @@ function Courseplay:loadMap(filename) g_currentMission.missionInfo.savegameIndex) self:load() self:setupGui() + self:loadUserSettings() if g_currentMission.missionInfo.savegameDirectory ~= nil then local saveGamePath = g_currentMission.missionInfo.savegameDirectory .."/" local filePath = saveGamePath .. "Courseplay.xml" diff --git a/config/MasterTranslations.xml b/config/MasterTranslations.xml index 85d44e07..4d4b4719 100644 --- a/config/MasterTranslations.xml +++ b/config/MasterTranslations.xml @@ -1778,6 +1778,10 @@ The course is saved automatically on closing of the editor and overrides the sel + + + + diff --git a/modDesc.xml b/modDesc.xml index 70a4d6fa..5bbdc64e 100644 --- a/modDesc.xml +++ b/modDesc.xml @@ -489,8 +489,7 @@ Changelog 7.1.0.0: - + diff --git a/scripts/courseManager/FileSystem.lua b/scripts/courseManager/FileSystem.lua index 2609757c..732bfe77 100644 --- a/scripts/courseManager/FileSystem.lua +++ b/scripts/courseManager/FileSystem.lua @@ -123,13 +123,14 @@ end function File:load(xmlSchema, xmlBaseKey, lambda, class,...) local xmlFile = XMLFile.load("tempXmlFile", self.fullPath, xmlSchema) if xmlFile ~= nil then + local retValue = false if class then - lambda(class, xmlFile, xmlBaseKey, ..., self.name) + retValue = lambda(class, xmlFile, xmlBaseKey, ..., self.name) else - lambda(xmlFile, xmlBaseKey, ..., self.name) + retValue = lambda(xmlFile, xmlBaseKey, ..., self.name) end xmlFile:delete() - return true + return retValue end CpUtil.debugFormat(CpDebug.DBG_COURSES, "couldn't load xml file: %s", self.fullPath) return false @@ -635,6 +636,10 @@ function DirectoryView:getEntryByName(name) end end +function DirectoryView:hasEntryWithName(name) + return self:getEntryByName(name) ~= nil +end + --- File system to handle multiple files/directions. ---@class FileSystem FileSystem = CpObject() diff --git a/scripts/editor/CourseEditor.lua b/scripts/editor/CourseEditor.lua index 91de51b4..bf252fa1 100644 --- a/scripts/editor/CourseEditor.lua +++ b/scripts/editor/CourseEditor.lua @@ -28,20 +28,28 @@ end --- Loads the course, might be a good idea to consolidate this with the loading of CpCourseManager. function CourseEditor:loadCourse() local function load(self, xmlFile, baseKey, noEventSend, name) + local course = nil xmlFile:iterate(baseKey, function (i, key) CpUtil.debugVehicle(CpDebug.DBG_COURSES, self, "Loading assigned course: %s", key) - local course = Course.createFromXml(nil, xmlFile, key) + course = Course.createFromXml(nil, xmlFile, key) course:setName(name) + end) + if course then self.courseWrapper = EditorCourseWrapper(course) - end) + return true + end + return false end - self.file:load(CpCourseManager.xmlSchema, CpCourseManager.xmlKeyFileManager, - load, self, false) - self.courseDisplay:setCourse(self.courseWrapper) - local course = self.courseWrapper:getCourse() - if course and course:getMultiTools() > 1 then - self.needsMultiToolDialog = true + if self.file:load(CpCourseManager.xmlSchema, CpCourseManager.xmlKeyFileManager, + load, self, false) then + self.courseDisplay:setCourse(self.courseWrapper) + local course = self.courseWrapper:getCourse() + if course and course:getMultiTools() > 1 then + self.needsMultiToolDialog = true + end + return true end + return false end --- Saves the course, might be a good idea to consolidate this with the saving of CpCourseManager. @@ -96,12 +104,15 @@ function CourseEditor:activate(file) return end if file then - self.isActive = true - self.file = file - self:loadCourse() - g_gui:showGui("ShopMenu") - g_shopMenu:onButtonConstruction() + if self:loadCourse() then + self.isActive = true + self.file = file + g_gui:showGui("ShopMenu") + g_shopMenu:onButtonConstruction() + return true + end end + return false end function CourseEditor:activateCustomField(file, field) diff --git a/scripts/field/CustomField.lua b/scripts/field/CustomField.lua index 82bbd2a6..fa68e66a 100644 --- a/scripts/field/CustomField.lua +++ b/scripts/field/CustomField.lua @@ -25,16 +25,12 @@ along with this program. If not, see . ---@class CustomField CustomField = CpObject() - -CustomField.xmlSchema = XMLSchema.new("customField") -CustomField.xmlSchema:register(XMLValueType.STRING ,"customField#name", "Name") -- for backwards compatibility -CustomField.xmlSchema:register(XMLValueType.STRING ,"customField.vertices", "Vertices of the field polygon") - CustomField.rootXmlKey = "customField" - -function CustomField:init() - -end +CustomField.vertexKey = "vertex" +CustomField.xmlSchema = XMLSchema.new(CustomField.rootXmlKey) +CustomField.xmlSchema:register(XMLValueType.VECTOR_2, + string.format("%s.%s(?)", CustomField.rootXmlKey, CustomField.vertexKey), + "Vertices of the field polygon") function CustomField:setup(name, vertices) @@ -81,8 +77,7 @@ function CustomField:draw(map) if not self.fieldHotspot then -- add hotspot when draw first called. Can't create in the constructor as on game load -- when the custom fields are loaded there's no player yet - -- TODO_25 - -- self:addHotspot() + self:addHotspot() end self.fieldPlot:draw(map) end @@ -128,15 +123,26 @@ function CustomField:findFieldCenter() self.posZ = z / #self.vertices end +function CustomField:getCenter() + return self.posX, self.posZ +end -function CustomField:saveToXml(xmlFile, baseKey,name) - xmlFile:setValue(baseKey .. '#name', name) - xmlFile:setValue(baseKey .. '.vertices', self:serializeVertices()) +function CustomField:saveToXml(xmlFile, baseKey, name) + for i=1, #self.vertices do + xmlFile:setValue(string.format('%s.%s(%d)', baseKey, self.vertexKey, i-1), self.vertices[i].x, self.vertices[i].z ) + end end -function CustomField:loadFromXml(xmlFile,baseKey) - local vertices = CustomField.deserializeVertices(xmlFile:getValue(baseKey .. '.vertices')) - self:setup(nil,vertices) +function CustomField:loadFromXml(xmlFile, baseKey) + local vertices = {} + xmlFile:iterate(baseKey .. "." .. self.vertexKey, function (_, key) + local x, z = xmlFile:getValue(key) + table.insert(vertices, {x = x, z = z}) + end) + if #vertices > 0 then + self:setup(nil, vertices) + return true + end end function CustomField:writeStream(streamId, connection) @@ -169,12 +175,17 @@ function CustomField.deserializeVertices(serializedVertices) return vertices end +--- Trys to load a custom field +---@param file File +---@return CustomField|nil function CustomField.createFromXmlFile(file) local field = CustomField() - file:load(CustomField.xmlSchema,CustomField.rootXmlKey, - CustomField.loadFromXml,field) - field:setName(file:getName()) - return field + if file:load(CustomField.xmlSchema, CustomField.rootXmlKey, + CustomField.loadFromXml, field) then + field:setName(file:getName()) + return field + end + return nil end function CustomField.createFromStream(streamId, connection) diff --git a/scripts/field/CustomFieldManager.lua b/scripts/field/CustomFieldManager.lua index 32f097dd..0f9a90f0 100644 --- a/scripts/field/CustomFieldManager.lua +++ b/scripts/field/CustomFieldManager.lua @@ -40,34 +40,37 @@ function CustomFieldManager:load() self.fileSystem:refresh() local entries = self.rootDir:getEntries(false, true) for i, entry in pairs(entries) do - table.insert(self.fields, CustomField.createFromXmlFile(entry)) + local field = CustomField.createFromXmlFile(entry) + if field == nil then + CpUtil.info("Failed to load custom field: %s", tostring(entry)) + else + table.insert(self.fields, CustomField.createFromXmlFile(entry)) + end end --- Adds reference to the custom fields, for extern mod support. g_fieldManager.cpCustomFields = self.fields end --- New fields are created with a prefix and the next available number. +---@return number function CustomFieldManager:getNewFieldNumber() local numbers = {} for i, entry in pairs(self.fields) do local name = entry:getName() if name:startsWith("CP-") then local n = entry:getFieldNumber() - if n then - table.insert(numbers, entry) - end + numbers[n] = true end end - table.sort(numbers, function (a, b) return a:getFieldNumber() < b:getFieldNumber() end) - for i, entry in pairs(numbers) do - if i ~= entry:getFieldNumber() then - -- the i. entry is not i, so we can use i as a new number (entries is sorted) - return i - end + local ix = 1 + while self.currentView:hasEntryWithName(self.namePrefix..tostring(ix)) or numbers[ix] do + ix = ix + 1 end - return #numbers + 1 + return ix end +--- Creates a new custom field from a given vertices table. +---@param waypoints table function CustomFieldManager:addField(waypoints) if #waypoints < 10 then CpUtil.info('Recorded course has less than 10 waypoints, ignoring.') @@ -82,7 +85,8 @@ function CustomFieldManager:addField(waypoints) nil, nil, nil, nil, nil, nil, newField) end - +--- Tries to delete a given custom field. +---@param fieldToDelete CustomField function CustomFieldManager:deleteField(fieldToDelete) YesNoDialog.show( CustomFieldManager.onClickDeleteDialog, self, @@ -90,7 +94,9 @@ function CustomFieldManager:deleteField(fieldToDelete) nil, nil, nil, nil, nil, nil, fieldToDelete) end -function CustomFieldManager:renameField(field, hotspot) +--- Tries renames a given custom field +---@param field CustomField +function CustomFieldManager:renameField(field) TextInputDialog.show( CustomFieldManager.onClickRenameDialog, self, field:getName() or "", @@ -98,7 +104,9 @@ function CustomFieldManager:renameField(field, hotspot) nil, 30, g_i18n:getText("button_ok"), field) end -function CustomFieldManager:editField(fieldToEdit, hotspot) +--- Tries to edit a given custom field, with the course editor. +---@param fieldToEdit CustomField +function CustomFieldManager:editField(fieldToEdit) for i, field in pairs(self.fields) do if field == fieldToEdit then local file = self.currentView:getEntryByName(fieldToEdit:getName()) @@ -109,13 +117,17 @@ function CustomFieldManager:editField(fieldToEdit, hotspot) end end +--- Saves the given custom field +---@param file File +---@param field CustomField +---@param forceReload boolean|nil function CustomFieldManager:saveField(file, field, forceReload) file:save(CustomField.rootXmlKey, - CustomField.xmlSchema, - CustomField.rootXmlKey, - CustomField.saveToXml, - field, - field:getName()) + CustomField.xmlSchema, + CustomField.rootXmlKey, + CustomField.saveToXml, + field, + field:getName()) if forceReload then self:delete() self:load() @@ -133,6 +145,8 @@ function CustomFieldManager:onClickSaveDialog(clickOk, field) fieldValid = true table.insert(self.fields, field) self.fileSystem:refresh() + else + CpUtil.info("Failed to create custom Field: %s", field:getName()) end end if not fieldValid then diff --git a/scripts/gui/CpInGameMenu.lua b/scripts/gui/CpInGameMenu.lua index d0d23584..6087f4d4 100644 --- a/scripts/gui/CpInGameMenu.lua +++ b/scripts/gui/CpInGameMenu.lua @@ -1,4 +1,6 @@ -CpInGameMenu = {} +CpInGameMenu = { + BASE_XML_KEY = "InGameMenu" +} local CpInGameMenu_mt = Class(CpInGameMenu, TabbedMenu) function CpInGameMenu.new(target, customMt, messageCenter, l10n, inputManager, courseStorage) local self = CpInGameMenu:superClass().new(target, customMt or CpInGameMenu_mt, messageCenter, l10n, inputManager) @@ -103,7 +105,33 @@ function CpInGameMenu.setupGui(courseStorage) "CpInGameMenu", g_cpInGameMenu) end --- Lines 279-324 +function CpInGameMenu.registerXmlSchema(xmlSchema, xmlKey) + xmlKey = xmlKey .. CpInGameMenu.BASE_XML_KEY .. "." + CpCourseGeneratorFrame.registerXmlSchema(xmlSchema, xmlKey) + CpGlobalSettingsFrame.registerXmlSchema(xmlSchema, xmlKey) + CpVehicleSettingsFrame.registerXmlSchema(xmlSchema, xmlKey) + CpCourseManagerFrame.registerXmlSchema(xmlSchema, xmlKey) + CpHelpFrame.registerXmlSchema(xmlSchema, xmlKey) +end + +function CpInGameMenu:loadFromXMLFile(xmlFile, baseKey) + baseKey = baseKey .. CpInGameMenu.BASE_XML_KEY .. "." + self.pageCourseGenerator:loadFromXMLFile(xmlFile, baseKey) + self.pageGlobalSettings:loadFromXMLFile(xmlFile, baseKey) + self.pageVehicleSettings:loadFromXMLFile(xmlFile, baseKey) + self.pageCourseManager:loadFromXMLFile(xmlFile, baseKey) + self.pageHelpLine:loadFromXMLFile(xmlFile, baseKey) +end + +function CpInGameMenu:saveToXMLFile(xmlFile, baseKey) + baseKey = baseKey .. CpInGameMenu.BASE_XML_KEY .. "." + self.pageCourseGenerator:saveToXMLFile(xmlFile, baseKey) + self.pageGlobalSettings:saveToXMLFile(xmlFile, baseKey) + self.pageVehicleSettings:saveToXMLFile(xmlFile, baseKey) + self.pageCourseManager:saveToXMLFile(xmlFile, baseKey) + self.pageHelpLine:saveToXMLFile(xmlFile, baseKey) +end + function CpInGameMenu:initializePages() self.clickBackCallback = function () if self.currentPage.onClickBack then @@ -115,13 +143,13 @@ function CpInGameMenu:initializePages() self.pageCourseGenerator:setInGameMap( g_inGameMenu.baseIngameMap, g_currentMission.hud) + self.pageCourseManager:setCourseStorage(self.courseStorage) self.pageHelpLine:initialize(self) self.pageGlobalSettings:initialize(self) self.pageVehicleSettings:initialize(self) self.pageCourseGenerator:initialize(self) self.pageCourseManager:initialize(self) - self.pageCourseManager:setCourseStorage(self.courseStorage) end -- Lines 327-362 diff --git a/scripts/gui/CpAIHotspots.lua b/scripts/gui/CustomFieldHotspot.lua similarity index 55% rename from scripts/gui/CpAIHotspots.lua rename to scripts/gui/CustomFieldHotspot.lua index 572b6605..2ae8133d 100644 --- a/scripts/gui/CpAIHotspots.lua +++ b/scripts/gui/CustomFieldHotspot.lua @@ -1,21 +1,42 @@ --- Custom field hotspot that can be clicked for deleting of the field course. CustomFieldHotspot = {} CustomFieldHotspot.CATEGORY = 200 -local CustomFieldHotspot_mt = Class(CustomFieldHotspot, FieldHotspot) +CustomFieldHotspot.SLICE_ID = "gui.ingameMap_other" +CustomFieldHotspot.NAME = "CP_customFieldManager_hotspotName" +CustomFieldHotspot.COLOR = {0.61049, 0.56471, 0.00303, 1} +local CustomFieldHotspot_mt = Class(CustomFieldHotspot, FarmlandHotspot) function CustomFieldHotspot.new(customMt) - local self = FieldHotspot.new(customMt or CustomFieldHotspot_mt) - + local self = FarmlandHotspot.new(customMt or CustomFieldHotspot_mt) + self.lastName = "" return self end +function CustomFieldHotspot:render(x, y, rotation, small) + local name = self:getName() + if name ~= self.lastName then + setTextBold(true) + local width = getTextWidth(self.textSize * 1/(self.scale * 0.75), self.field:getName()) + setTextBold(false) + self.icon:setDimension(width + self.width) + end + self.lastName = name + CustomFieldHotspot:superClass().render(self, x, y, rotation, small) +end + +function CustomFieldHotspot:setScale(scale) + self.scale = scale +end + function CustomFieldHotspot:getCategory() return CustomFieldHotspot.CATEGORY end +---@param field CustomField function CustomFieldHotspot:setField(field) - CustomFieldHotspot:superClass().setField(self, field) - + self.field = field + local worldX, worldZ = field:getCenter() + self:setWorldPosition(worldX, worldZ) self.clickArea = MapHotspot.getClickArea( { 0, @@ -30,6 +51,10 @@ function CustomFieldHotspot:setField(field) ) end +function CustomFieldHotspot:getName() + return self.field:getName() +end + function CustomFieldHotspot:onClickDelete() CpUtil.debugFormat(CpDebug.DBG_HUD,"Delete custom field %s.", self.name) g_customFieldManager:deleteField(self.field) @@ -50,21 +75,3 @@ function CustomFieldHotspot:getAreaText() return g_i18n:formatArea(self.field:getAreaInSqMeters()/10000 , 2) end ---- Enables field hotspot area content box. -FieldHotspot.clickArea = MapHotspot.getClickArea( - { - 0, - 0, - 1, - 1 - }, - { - 1,1, - }, - 0 -) - -FieldHotspot.getAreaText = function (self) - --- Is already in ha. - return g_i18n:formatArea(self.field.fieldArea , 2) -end \ No newline at end of file diff --git a/scripts/gui/pages/CpCourseGeneratorFrame.lua b/scripts/gui/pages/CpCourseGeneratorFrame.lua index 051d9ae1..4b932b3d 100644 --- a/scripts/gui/pages/CpCourseGeneratorFrame.lua +++ b/scripts/gui/pages/CpCourseGeneratorFrame.lua @@ -44,6 +44,8 @@ CpCourseGeneratorFrame = { MAP_SELECTOR_HOTSPOT = 1, MAP_SELECTOR_CREATE_JOB = 2, MAP_SELECTOR_ACTIVE_JOBS = 3, + CP_MAP_HOTSPOT_OFFSET = 200, + BASE_XML_KEY = "CourseGenerator" -- POSITION_UVS = GuiUtils.getUVs({ -- 760, @@ -94,6 +96,7 @@ function CpCourseGeneratorFrame.new(target, custom_mt) g_i18n:getText("button_createJob"), g_i18n:getText("ui_activeAIJobs")} + self.cpHotspotSettingValue = 1 return self end @@ -113,6 +116,22 @@ function CpCourseGeneratorFrame.createFromExistingGui(gui, guiName) return newGui end +function CpCourseGeneratorFrame.registerXmlSchema(xmlSchema, xmlKey) + xmlKey = xmlKey .. CpCourseGeneratorFrame.BASE_XML_KEY + xmlSchema:register(XMLValueType.INT, xmlKey .. "#mapHotspotValue", "Selected hotspots") +end + + +function CpCourseGeneratorFrame:loadFromXMLFile(xmlFile, baseKey) + self.cpHotspotSettingValue = xmlFile:getValue( + string.format("%s%s#mapHotspotValue", baseKey, self.BASE_XML_KEY), 0xFF) +end + +function CpCourseGeneratorFrame:saveToXMLFile(xmlFile, baseKey) + xmlFile:setValue(string.format("%s%s#mapHotspotValue", + baseKey, self.BASE_XML_KEY), self.cpHotspotSettingValue) +end + function CpCourseGeneratorFrame:setInGameMap(ingameMap, hud) self.ingameMapBase = ingameMap self.ingameMap:setIngameMap(ingameMap) @@ -173,7 +192,14 @@ function CpCourseGeneratorFrame:initialize(menu) self.mapOverviewSelector:setTexts(self.mapSelectorTexts) self.mapOverviewSelector:setState(1, true) - self.hotspotFilterCategories = InGameMenuMapFrame.HOTSPOT_FILTER_CATEGORIES + self.hotspotFilterCategories = table.clone(InGameMenuMapFrame.HOTSPOT_FILTER_CATEGORIES) + table.insert(self.hotspotFilterCategories[2], { + ["id"] = CustomFieldHotspot.CATEGORY, + ["sliceId"] = CustomFieldHotspot.SLICE_ID, + ["name"] = CustomFieldHotspot.NAME, + ["color"] = {CustomFieldHotspot.COLOR}}) + self.CUSTOM_FIELD_HOTSPOTS = #self.hotspotFilterCategories[2] + self.hotspotStateFilter = {} for i, data in ipairs(self.hotspotFilterCategories) do self.hotspotStateFilter[i] = {} @@ -287,11 +313,17 @@ function CpCourseGeneratorFrame:onFrameOpen() local hotspotValue = g_gameSettings:getValue(GameSettings.SETTING.INGAME_MAP_HOTSPOT_FILTER) for i, hotspotCategory in pairs(self.hotspotFilterCategories[1]) do local isBitSet = Utils.isBitSet(hotspotValue, hotspotCategory.id) + if hotspotCategory.id >= self.CP_MAP_HOTSPOT_OFFSET then + isBitSet = Utils.isBitSet(self.cpHotspotSettingValue, hotspotCategory.id - self.CP_MAP_HOTSPOT_OFFSET) + end self.hotspotStateFilter[1][i] = isBitSet self.ingameMapBase:setDefaultFilterValue(hotspotCategory.id, isBitSet) end for i, hotspotCategory in pairs(self.hotspotFilterCategories[2]) do local isBitSet = Utils.isBitSet(hotspotValue, hotspotCategory.id) + if hotspotCategory.id >= self.CP_MAP_HOTSPOT_OFFSET then + isBitSet = Utils.isBitSet(self.cpHotspotSettingValue, hotspotCategory.id - self.CP_MAP_HOTSPOT_OFFSET) + end self.hotspotStateFilter[2][i] = isBitSet self.ingameMapBase:setDefaultFilterValue(hotspotCategory.id, isBitSet) end @@ -335,19 +367,30 @@ function CpCourseGeneratorFrame:onFrameOpen() self:updateSubCategoryPages(self.CATEGRORIES.IN_GAME_MAP) self:setMapSelectionItem(nil) end - + g_customFieldManager:refresh() end function CpCourseGeneratorFrame:saveHotspotFilter() local hotspotValue = 0 + self.cpHotspotSettingValue = 0 for i, state in pairs(self.hotspotStateFilter[1]) do if state then - hotspotValue = Utils.setBit(hotspotValue, i) + local id = self.hotspotFilterCategories[1][i].id + if id >= self.CP_MAP_HOTSPOT_OFFSET then + self.cpHotspotSettingValue = Utils.setBit(self.cpHotspotSettingValue, id - self.CP_MAP_HOTSPOT_OFFSET) + else + hotspotValue = Utils.setBit(hotspotValue, id) + end end end for i, state in pairs(self.hotspotStateFilter[2]) do if state then - hotspotValue = Utils.setBit(hotspotValue, i + #self.hotspotStateFilter[1]) + local id = self.hotspotFilterCategories[2][i].id + if id >= self.CP_MAP_HOTSPOT_OFFSET then + self.cpHotspotSettingValue = Utils.setBit(self.cpHotspotSettingValue, id - self.CP_MAP_HOTSPOT_OFFSET) + else + hotspotValue = Utils.setBit(hotspotValue, id) + end end end g_gameSettings:setValue(GameSettings.SETTING.INGAME_MAP_HOTSPOT_FILTER, hotspotValue, true) @@ -543,8 +586,10 @@ function CpCourseGeneratorFrame:onDrawPostIngameMap(element, ingameMap) elseif vehicle and vehicle.drawCpCoursePlot then vehicle:drawCpCoursePlot(ingameMap) end - -- show the custom fields on the AI map - g_customFieldManager:draw(ingameMap) + if self.hotspotStateFilter[2][self.CUSTOM_FIELD_HOTSPOTS] then + -- show the custom fields on the AI map + g_customFieldManager:draw(ingameMap) + end -- show the selected field on the AI screen map when creating a job if self.currentJob and self.currentJob.draw then self.currentJob:draw(ingameMap, self.mode == self.MODE_OVERVIEW) diff --git a/scripts/gui/pages/CpCourseManagerFrame.lua b/scripts/gui/pages/CpCourseManagerFrame.lua index 32f704ed..419a98f2 100644 --- a/scripts/gui/pages/CpCourseManagerFrame.lua +++ b/scripts/gui/pages/CpCourseManagerFrame.lua @@ -83,6 +83,18 @@ function CpCourseManagerFrame.setupGui() "CpCourseManagerFrame", courseManagerFrame, true) end +function CpCourseManagerFrame.registerXmlSchema(xmlSchema, xmlKey) + +end + +function CpCourseManagerFrame:loadFromXMLFile(xmlFile, baseKey) + +end + +function CpCourseManagerFrame:saveToXMLFile(xmlFile, baseKey) + +end + function CpCourseManagerFrame:setCourseStorage(courseStorage) self.courseStorage = courseStorage end @@ -133,7 +145,9 @@ function CpCourseManagerFrame:initialize(menu) if viewEntry then if not viewEntry:isDirectory() then local vehicle = CpUtil.getCurrentVehicle() - vehicle:appendLoadedCpCourse(viewEntry:getEntity()) + if not vehicle:appendLoadedCpCourse(viewEntry:getEntity()) then + --TODO_25 Error message missing! + end else self.showInfoDialog( self.translations.targetIsNoCourse, viewEntry) diff --git a/scripts/gui/pages/CpGlobalSettingsFrame.lua b/scripts/gui/pages/CpGlobalSettingsFrame.lua index 485cbe8a..de3bdc2c 100644 --- a/scripts/gui/pages/CpGlobalSettingsFrame.lua +++ b/scripts/gui/pages/CpGlobalSettingsFrame.lua @@ -40,6 +40,18 @@ function CpGlobalSettingsFrame.createFromExistingGui(gui, guiName) return newGui end +function CpGlobalSettingsFrame.registerXmlSchema(xmlSchema, xmlKey) + +end + +function CpGlobalSettingsFrame:loadFromXMLFile(xmlFile, baseKey) + +end + +function CpGlobalSettingsFrame:saveToXMLFile(xmlFile, baseKey) + +end + function CpGlobalSettingsFrame:initialize(menu) self.booleanPrefab:unlinkElement() diff --git a/scripts/gui/pages/CpHelpFrame.lua b/scripts/gui/pages/CpHelpFrame.lua index deace94b..a1372a98 100644 --- a/scripts/gui/pages/CpHelpFrame.lua +++ b/scripts/gui/pages/CpHelpFrame.lua @@ -27,6 +27,18 @@ function CpHelpFrame.createFromExistingGui(gui, guiName) return newGui end +function CpHelpFrame.registerXmlSchema(xmlSchema, xmlKey) + +end + +function CpHelpFrame:loadFromXMLFile(xmlFile, baseKey) + +end + +function CpHelpFrame:saveToXMLFile(xmlFile, baseKey) + +end + function CpHelpFrame:initialize(menu) self.helpLineDotTemplate:unlinkElement() FocusManager:removeElement(self.helpLineDotTemplate) diff --git a/scripts/gui/pages/CpVehicleSettingsFrame.lua b/scripts/gui/pages/CpVehicleSettingsFrame.lua index c17f9d45..70b927bd 100644 --- a/scripts/gui/pages/CpVehicleSettingsFrame.lua +++ b/scripts/gui/pages/CpVehicleSettingsFrame.lua @@ -38,6 +38,18 @@ function CpVehicleSettingsFrame.createFromExistingGui(gui, guiName) return newGui end +function CpVehicleSettingsFrame.registerXmlSchema(xmlSchema, xmlKey) + +end + +function CpVehicleSettingsFrame:loadFromXMLFile(xmlFile, baseKey) + +end + +function CpVehicleSettingsFrame:saveToXMLFile(xmlFile, baseKey) + +end + function CpVehicleSettingsFrame:initialize(menu) self.cpMenu = menu self.booleanPrefab:unlinkElement() diff --git a/scripts/specializations/CpCourseManager.lua b/scripts/specializations/CpCourseManager.lua index 35ea9220..2dabee79 100644 --- a/scripts/specializations/CpCourseManager.lua +++ b/scripts/specializations/CpCourseManager.lua @@ -88,7 +88,7 @@ function CpCourseManager.registerFunctions(vehicleType) SpecializationUtil.registerFunction(vehicleType, 'hasCpCourse', CpCourseManager.hasCourse) SpecializationUtil.registerFunction(vehicleType, 'cpCopyCourse', CpCourseManager.cpCopyCourse) - SpecializationUtil.registerFunction(vehicleType, 'appendLoadedCpCourse', CpCourseManager.appendLoadedCourse) + SpecializationUtil.registerFunction(vehicleType, 'appendLoadedCpCourse', CpCourseManager.appendLoadedCpCourse) SpecializationUtil.registerFunction(vehicleType, 'saveCpCourses', CpCourseManager.saveCourses) SpecializationUtil.registerFunction(vehicleType, 'resetCpCourses', CpCourseManager.resetCourses) SpecializationUtil.registerFunction(vehicleType, 'resetCpCoursesFromGui', CpCourseManager.resetCpCoursesFromGui) @@ -148,7 +148,7 @@ function CpCourseManager:loadAssignedCourses(xmlFile, baseKey, noEventSend, name CpUtil.debugVehicle(CpDebug.DBG_COURSES,self,"Loading assigned course: %s",key) local course = Course.createFromXml(self,xmlFile,key) course:setVehicle(self) - table.insert(courses,course) + table.insert(courses, course) end) if courses ~= nil and next(courses) then spec.courses = courses @@ -385,11 +385,14 @@ function CpCourseManager.getCourseName(course) return name end -function CpCourseManager:appendLoadedCourse(file) +--- Trys to load a course from the file system +---@param file File +---@return boolean success +function CpCourseManager:appendLoadedCpCourse(file) --- For now clear the previous courses. CpCourseManager.resetCourses(self) - file:load(CpCourseManager.xmlSchema, CpCourseManager.xmlKeyFileManager, - CpCourseManager.loadAssignedCourses, self, false) + return file:load(CpCourseManager.xmlSchema, CpCourseManager.xmlKeyFileManager, + CpCourseManager.loadAssignedCourses, self, false) end function CpCourseManager:saveCourses(file,text) @@ -430,10 +433,6 @@ function CpCourseManager:cpReverseCurrentCourse(noEventSend) end end -function CpCourseManager:appendCourse(course) - -end - function CpCourseManager:rememberCpLastWaypointIx(ix) local spec = self.spec_cpCourseManager spec.rememberedWpIx = ix diff --git a/scripts/test/CourseManagerTest.lua b/scripts/test/CourseManagerTest.lua index 1330e89b..6380f274 100644 --- a/scripts/test/CourseManagerTest.lua +++ b/scripts/test/CourseManagerTest.lua @@ -25,7 +25,7 @@ assert(file.fullPath == coursesDir .. "/" .. "testFile") file:save("xmlRootName",{},"xmlBaseKey",function () end,{},...) -file:load({},"xmlBaseKey",function () end,{},...) +file:load({},"xmlBaseKey",function () return true end,{},...) file:delete() assert(not fileExists(file:getFullPath())) From cd552a07072635aa33e96bbe0c30fbeed1ae2730 Mon Sep 17 00:00:00 2001 From: schwiti6190 Date: Mon, 16 Dec 2024 14:52:25 +0000 Subject: [PATCH 2/3] Updated translations --- translations/translation_br.xml | 1 + translations/translation_cs.xml | 1 + translations/translation_ct.xml | 1 + translations/translation_cz.xml | 1 + translations/translation_da.xml | 1 + translations/translation_de.xml | 1 + translations/translation_ea.xml | 1 + translations/translation_en.xml | 1 + translations/translation_es.xml | 1 + translations/translation_fc.xml | 1 + translations/translation_fi.xml | 1 + translations/translation_fr.xml | 1 + translations/translation_hu.xml | 1 + translations/translation_it.xml | 1 + translations/translation_jp.xml | 1 + translations/translation_kr.xml | 1 + translations/translation_nl.xml | 1 + translations/translation_no.xml | 1 + translations/translation_pl.xml | 1 + translations/translation_pt.xml | 1 + translations/translation_ro.xml | 1 + translations/translation_ru.xml | 1 + translations/translation_sv.xml | 1 + translations/translation_tr.xml | 1 + 24 files changed, 24 insertions(+) diff --git a/translations/translation_br.xml b/translations/translation_br.xml index 0f9e17cc..7588be1e 100644 --- a/translations/translation_br.xml +++ b/translations/translation_br.xml @@ -504,6 +504,7 @@ A rota é salva automaticamente ao fechar o editor e substituir a rota seleciona + diff --git a/translations/translation_cs.xml b/translations/translation_cs.xml index 916209ea..201799ef 100644 --- a/translations/translation_cs.xml +++ b/translations/translation_cs.xml @@ -504,6 +504,7 @@ + diff --git a/translations/translation_ct.xml b/translations/translation_ct.xml index 906a1091..9daef4b7 100644 --- a/translations/translation_ct.xml +++ b/translations/translation_ct.xml @@ -504,6 +504,7 @@ + diff --git a/translations/translation_cz.xml b/translations/translation_cz.xml index 91cc4ae3..c157eca8 100644 --- a/translations/translation_cz.xml +++ b/translations/translation_cz.xml @@ -504,6 +504,7 @@ Trasa se automaticky uloží při zavření editoru a přepíše vybranou trasu. + diff --git a/translations/translation_da.xml b/translations/translation_da.xml index b1cc6a48..e62eae62 100644 --- a/translations/translation_da.xml +++ b/translations/translation_da.xml @@ -504,6 +504,7 @@ Ruten gemmes automatisk ved lukning af editoren og tilsidesætter den valgte rut + diff --git a/translations/translation_de.xml b/translations/translation_de.xml index c418a938..6ce031ca 100644 --- a/translations/translation_de.xml +++ b/translations/translation_de.xml @@ -504,6 +504,7 @@ Der Kurs wird beim Schließen automatisch gespeichert und überschrieben. + diff --git a/translations/translation_ea.xml b/translations/translation_ea.xml index a8fdcfff..2d0c19dc 100644 --- a/translations/translation_ea.xml +++ b/translations/translation_ea.xml @@ -504,6 +504,7 @@ The course is saved automatically on closing of the editor and overrides the sel + diff --git a/translations/translation_en.xml b/translations/translation_en.xml index 8f58ed55..272c0973 100644 --- a/translations/translation_en.xml +++ b/translations/translation_en.xml @@ -504,6 +504,7 @@ The course is saved automatically on closing of the editor and overrides the sel + diff --git a/translations/translation_es.xml b/translations/translation_es.xml index 5f753ae8..835afce2 100644 --- a/translations/translation_es.xml +++ b/translations/translation_es.xml @@ -504,6 +504,7 @@ El curso se guarda automáticamente al cerrar el editor y anula el curso selecci + diff --git a/translations/translation_fc.xml b/translations/translation_fc.xml index ef69c963..0ff4776a 100644 --- a/translations/translation_fc.xml +++ b/translations/translation_fc.xml @@ -504,6 +504,7 @@ The course is saved automatically on closing of the editor and overrides the sel + diff --git a/translations/translation_fi.xml b/translations/translation_fi.xml index 315ba94d..e14525c5 100644 --- a/translations/translation_fi.xml +++ b/translations/translation_fi.xml @@ -504,6 +504,7 @@ The course is saved automatically on closing of the editor and overrides the sel + diff --git a/translations/translation_fr.xml b/translations/translation_fr.xml index f6022ed4..37c66359 100644 --- a/translations/translation_fr.xml +++ b/translations/translation_fr.xml @@ -504,6 +504,7 @@ La course est automatiquement sauvegardée à la fermeture de l'éditeur et remp + diff --git a/translations/translation_hu.xml b/translations/translation_hu.xml index 6cebcc37..d192c419 100644 --- a/translations/translation_hu.xml +++ b/translations/translation_hu.xml @@ -504,6 +504,7 @@ Az útvonal automatikusan mentésre kerül a szerkesztő bezárásakor és felü + diff --git a/translations/translation_it.xml b/translations/translation_it.xml index ad3098e7..343d500f 100644 --- a/translations/translation_it.xml +++ b/translations/translation_it.xml @@ -504,6 +504,7 @@ Il percorso viene salvato automaticamente alla chiusura dell'editor e sovrascriv + diff --git a/translations/translation_jp.xml b/translations/translation_jp.xml index d2a256fd..c492eada 100644 --- a/translations/translation_jp.xml +++ b/translations/translation_jp.xml @@ -504,6 +504,7 @@ The course is saved automatically on closing of the editor and overrides the sel + diff --git a/translations/translation_kr.xml b/translations/translation_kr.xml index 8133e94e..37729251 100644 --- a/translations/translation_kr.xml +++ b/translations/translation_kr.xml @@ -504,6 +504,7 @@ The course is saved automatically on closing of the editor and overrides the sel + diff --git a/translations/translation_nl.xml b/translations/translation_nl.xml index 7f2d1b68..458cb085 100644 --- a/translations/translation_nl.xml +++ b/translations/translation_nl.xml @@ -504,6 +504,7 @@ The course is saved automatically on closing of the editor and overrides the sel + diff --git a/translations/translation_no.xml b/translations/translation_no.xml index e367c51d..683fdc31 100644 --- a/translations/translation_no.xml +++ b/translations/translation_no.xml @@ -504,6 +504,7 @@ The course is saved automatically on closing of the editor and overrides the sel + diff --git a/translations/translation_pl.xml b/translations/translation_pl.xml index d84ef34c..e4a8809a 100644 --- a/translations/translation_pl.xml +++ b/translations/translation_pl.xml @@ -504,6 +504,7 @@ Kurs jest automatycznie zapisywany po zamknięciu edytora i nadpisuje wybrany ku + diff --git a/translations/translation_pt.xml b/translations/translation_pt.xml index 4a8ccfca..b67f5b06 100644 --- a/translations/translation_pt.xml +++ b/translations/translation_pt.xml @@ -504,6 +504,7 @@ A rota é guardada automaticamente ao fechar o editor e sobrepõe-se a qualquer + diff --git a/translations/translation_ro.xml b/translations/translation_ro.xml index 10c07257..1745d062 100644 --- a/translations/translation_ro.xml +++ b/translations/translation_ro.xml @@ -504,6 +504,7 @@ The course is saved automatically on closing of the editor and overrides the sel + diff --git a/translations/translation_ru.xml b/translations/translation_ru.xml index c5cbc7a9..57cce554 100644 --- a/translations/translation_ru.xml +++ b/translations/translation_ru.xml @@ -504,6 +504,7 @@ + diff --git a/translations/translation_sv.xml b/translations/translation_sv.xml index 84ac7f3e..e2a52b0a 100644 --- a/translations/translation_sv.xml +++ b/translations/translation_sv.xml @@ -504,6 +504,7 @@ Banan sparas automatiskt vid stängning av editorn och åsidosätter den valda b + diff --git a/translations/translation_tr.xml b/translations/translation_tr.xml index 9448c38e..b848090d 100644 --- a/translations/translation_tr.xml +++ b/translations/translation_tr.xml @@ -504,6 +504,7 @@ Editör kapatıldığında kurs otomatik olarak kaydedilir ve seçilen kursu ge + From c36fd53e26cae7d09fe605d13f507a53dd31df7a Mon Sep 17 00:00:00 2001 From: David Schwietering Date: Tue, 17 Dec 2024 20:11:24 +0100 Subject: [PATCH 3/3] Added missing doc --- scripts/gui/pages/CpCourseGeneratorFrame.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/gui/pages/CpCourseGeneratorFrame.lua b/scripts/gui/pages/CpCourseGeneratorFrame.lua index 4b932b3d..81a98100 100644 --- a/scripts/gui/pages/CpCourseGeneratorFrame.lua +++ b/scripts/gui/pages/CpCourseGeneratorFrame.lua @@ -96,6 +96,7 @@ function CpCourseGeneratorFrame.new(target, custom_mt) g_i18n:getText("button_createJob"), g_i18n:getText("ui_activeAIJobs")} + --- Bitmask for the visible cp hotspots. self.cpHotspotSettingValue = 1 return self end @@ -123,6 +124,8 @@ end function CpCourseGeneratorFrame:loadFromXMLFile(xmlFile, baseKey) + --- We save the hotspot setting in the Courseplay User settings, + --- as we don't want to pollute the giants hotspot setting. self.cpHotspotSettingValue = xmlFile:getValue( string.format("%s%s#mapHotspotValue", baseKey, self.BASE_XML_KEY), 0xFF) end @@ -311,9 +314,13 @@ function CpCourseGeneratorFrame:onFrameOpen() end, self) -- g_messageCenter:subscribe(MessageType.AI_TASK_SKIPPED, self.onAITaskSkipped, self) local hotspotValue = g_gameSettings:getValue(GameSettings.SETTING.INGAME_MAP_HOTSPOT_FILTER) + ------------------------------------------ + --- Loads the hotspot selection + ------------------------------------------ for i, hotspotCategory in pairs(self.hotspotFilterCategories[1]) do local isBitSet = Utils.isBitSet(hotspotValue, hotspotCategory.id) if hotspotCategory.id >= self.CP_MAP_HOTSPOT_OFFSET then + --- Every hotspot selection with a greater ID than X will be saved in the courseplay user settings. isBitSet = Utils.isBitSet(self.cpHotspotSettingValue, hotspotCategory.id - self.CP_MAP_HOTSPOT_OFFSET) end self.hotspotStateFilter[1][i] = isBitSet @@ -322,6 +329,7 @@ function CpCourseGeneratorFrame:onFrameOpen() for i, hotspotCategory in pairs(self.hotspotFilterCategories[2]) do local isBitSet = Utils.isBitSet(hotspotValue, hotspotCategory.id) if hotspotCategory.id >= self.CP_MAP_HOTSPOT_OFFSET then + --- Every hotspot selection with a greater ID than X will be saved in the courseplay user settings. isBitSet = Utils.isBitSet(self.cpHotspotSettingValue, hotspotCategory.id - self.CP_MAP_HOTSPOT_OFFSET) end self.hotspotStateFilter[2][i] = isBitSet