Skip to content

Commit

Permalink
Merge pull request #13 from Courseplay/Filesystem-adjustment
Browse files Browse the repository at this point in the history
Filesystem load check and custom field adjustments
  • Loading branch information
Tensuko authored Dec 17, 2024
2 parents 847f991 + c36fd53 commit d96a659
Show file tree
Hide file tree
Showing 40 changed files with 310 additions and 102 deletions.
5 changes: 4 additions & 1 deletion Courseplay.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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()
Expand All @@ -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
Expand Down Expand Up @@ -94,14 +97,14 @@ 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,
g_currentMission.missionInfo.savegameName,
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"
Expand Down
4 changes: 4 additions & 0 deletions config/MasterTranslations.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1778,6 +1778,10 @@ The course is saved automatically on closing of the editor and overrides the sel
</Translation>
</Category>
<Category name="Custom field manager">
<Translation name="CP_customFieldManager_hotspotName">
<Text language="de"><![CDATA[Randkurs]]></Text>
<Text language="en"><![CDATA[Custom field]]></Text>
</Translation>
<Translation name="CP_customFieldManager_confirm_save">
<Text language="de"><![CDATA[Möchtest du diesen benutzerdefinierten Randkurs als %s speichern?]]></Text>
<Text language="en"><![CDATA[Do you want to save the recorded course as custom field %s?]]></Text>
Expand Down
3 changes: 1 addition & 2 deletions modDesc.xml
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,7 @@ Changelog 7.1.0.0:
<sourceFile filename="scripts/gui/HeapPlot.lua"/>
<sourceFile filename="scripts/gui/UnloadingTriggerPlot.lua"/>
<sourceFile filename="scripts/gui/CpStatus.lua"/>
<!-- <sourceFile filename="scripts/gui/CpAIHotspots.lua"/>
<sourceFile filename="scripts/gui/CpAIFrameExtended.lua"/> -->
<sourceFile filename="scripts/gui/CustomFieldHotspot.lua"/>
<sourceFile filename="scripts/gui/CourseDisplay.lua"/>
<!-- <sourceFile filename="scripts/gui/CpGamePadHudScreen.lua"/> -->
<sourceFile filename="scripts/gui/elements/CpBinaryOptionElement.lua"/>
Expand Down
11 changes: 8 additions & 3 deletions scripts/courseManager/FileSystem.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
37 changes: 24 additions & 13 deletions scripts/editor/CourseEditor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand Down
53 changes: 32 additions & 21 deletions scripts/field/CustomField.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.

---@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)

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
52 changes: 33 additions & 19 deletions scripts/field/CustomFieldManager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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.')
Expand All @@ -82,23 +85,28 @@ 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,
string.format(g_i18n:getText("CP_customFieldManager_confirm_delete"), fieldToDelete:getName()),
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 "",
g_i18n:getText("CP_customFieldManager_rename"),
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())
Expand All @@ -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()
Expand All @@ -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
Expand Down
Loading

0 comments on commit d96a659

Please sign in to comment.