163 | function CropSensorLinkageData:getClonedCropSensorNode(typeName) |
164 | for i=1, #self.sensorData do |
165 | local sensorData = self.sensorData[i] |
166 | if sensorData.type:upper() == typeName:upper() then |
167 | local clonedData = table.copy(sensorData, 10) |
168 | clonedData.node = clone(sensorData.node, false, false, false) |
169 | |
170 | for j=1, #clonedData.rotationNodes do |
171 | local rotationNode = clonedData.rotationNodes[j] |
172 | rotationNode.node = I3DUtil.indexToObject(clonedData.node, rotationNode.nodePath) |
173 | end |
174 | |
175 | if clonedData.measurementNodePath ~= nil then |
176 | clonedData.measurementNode = I3DUtil.indexToObject(clonedData.node, clonedData.measurementNodePath) |
177 | end |
178 | |
179 | return clonedData |
180 | end |
181 | end |
182 | end |
57 | function CropSensorLinkageData:loadLinkageData(loadVehicleData, loadSensorData) |
58 | local filename = Utils.getFilename("CropSensorLinkageData.xml", CropSensorLinkageData.BASE_DIRECTORY) |
59 | |
60 | local xmlFile = XMLFile.load("CropSensorLinkageData", filename, CropSensorLinkageData.xmlSchema) |
61 | if xmlFile ~= nil then |
62 | self.configurationPrice = xmlFile:getValue("cropSensorLinkageData.configuration#price", 0) |
63 | |
64 | if loadVehicleData ~= false then |
65 | self.linkageData = {} |
66 | xmlFile:iterate("cropSensorLinkageData.vehicles.vehicle", function(index, key) |
67 | local vehicleData = {} |
68 | vehicleData.filename = xmlFile:getValue(key .. "#filename") |
69 | if vehicleData.filename ~= nil then |
70 | vehicleData.linkNodes = {} |
71 | |
72 | xmlFile:iterate(key .. ".linkNode", function(_, linkNodeKey) |
73 | local linkNode = {} |
74 | linkNode.nodeName = xmlFile:getValue(linkNodeKey .. "#node") |
75 | linkNode.typeName = xmlFile:getValue(linkNodeKey .. "#type", "SENSOR_LEFT"):upper() |
76 | linkNode.translation = xmlFile:getValue(linkNodeKey .. "#translation", "0 0 0", true) |
77 | linkNode.rotation = xmlFile:getValue(linkNodeKey .. "#rotation", "0 0 0", true) |
78 | |
79 | linkNode.rotationNodes = {} |
80 | xmlFile:iterate(linkNodeKey .. ".rotationNode", function(_, rotationNodeKey) |
81 | local rotatioNode = {} |
82 | rotatioNode.autoRotate = xmlFile:getValue(rotationNodeKey .. "#autoRotate") |
83 | rotatioNode.rotation = xmlFile:getValue(rotationNodeKey .. "#rotation", nil, true) |
84 | |
85 | table.insert(linkNode.rotationNodes, rotatioNode) |
86 | end) |
87 | |
88 | table.insert(vehicleData.linkNodes, linkNode) |
89 | end) |
90 | end |
91 | |
92 | table.insert(self.linkageData, vehicleData) |
93 | end) |
94 | end |
95 | |
96 | if loadSensorData ~= false then |
97 | local sensorsFilename = xmlFile:getValue("cropSensorLinkageData.sensors#filename") |
98 | if sensorsFilename ~= nil then |
99 | sensorsFilename = Utils.getFilename(sensorsFilename, CropSensorLinkageData.BASE_DIRECTORY) |
100 | g_i3DManager:loadI3DFileAsync(sensorsFilename, true, true, CropSensorLinkageData.onSensorDataLoaded, self, {xmlFile}) |
101 | else |
102 | xmlFile:delete() |
103 | end |
104 | else |
105 | xmlFile:delete() |
106 | end |
107 | end |
108 | |
109 | self.dataLoaded = true |
110 | |
111 | return true |
112 | end |
116 | function CropSensorLinkageData:onSensorDataLoaded(i3dNode, failedReason, args) |
117 | local xmlFile = unpack(args) |
118 | if i3dNode ~= 0 then |
119 | xmlFile:iterate("cropSensorLinkageData.sensors.sensor", function(index, key) |
120 | local sensorData = {} |
121 | sensorData.node = xmlFile:getValue(key .. "#node", nil, i3dNode) |
122 | if sensorData.node ~= nil then |
123 | sensorData.type = xmlFile:getValue(key .. "#type", "SENSOR_LEFT") |
124 | sensorData.measurementNodePath = xmlFile:getValue(key .. "#measurementNode") |
125 | sensorData.requiresDaylight = xmlFile:getValue(key .. "#requiresDaylight", true) |
126 | |
127 | sensorData.rotationNodes = {} |
128 | xmlFile:iterate(key .. ".rotationNode", function(_, rotationNodeKey) |
129 | local rotationNode = {} |
130 | rotationNode.nodePath = xmlFile:getValue(rotationNodeKey .. "#node") |
131 | rotationNode.autoRotate = xmlFile:getValue(rotationNodeKey .. "#autoRotate") |
132 | |
133 | table.insert(sensorData.rotationNodes, rotationNode) |
134 | end) |
135 | |
136 | table.insert(self.sensorData, sensorData) |
137 | end |
138 | end) |
139 | |
140 | for i=1, #self.sensorData do |
141 | unlink(self.sensorData[i].node) |
142 | end |
143 | |
144 | delete(i3dNode) |
145 | end |
146 | |
147 | xmlFile:delete() |
148 | end |
186 | function CropSensorLinkageData:overwriteGameFunctions(pfModule) |
187 | -- Reload linkage data while reloading vehicles to get the latest data |
188 | pfModule:overwriteGameFunction(FSBaseMission, "consoleCommandReloadVehicle", function(superFunc, mission, resetVehicle, radius) |
189 | self:loadLinkageData(true, false) |
190 | |
191 | return superFunc(mission, resetVehicle, radius) |
192 | end) |
193 | |
194 | pfModule:overwriteGameFunction(StoreItemUtil, "getConfigurationsFromXML", function(superFunc, xmlFile, key, baseDir, customEnvironment, isMod, storeItem) |
195 | local configurations, defaultConfigurationIds = superFunc(xmlFile, key, baseDir, customEnvironment, isMod, storeItem) |
196 | |
197 | if not self.dataLoaded then |
198 | self:loadLinkageData(true) |
199 | end |
200 | |
201 | local vehicleData = self:getCropSensorLinkageData(xmlFile.filename) |
202 | if vehicleData ~= nil then |
203 | if configurations == nil then |
204 | configurations = {} |
205 | end |
206 | |
207 | if defaultConfigurationIds == nil then |
208 | defaultConfigurationIds = {} |
209 | end |
210 | |
211 | configurations["cropSensor"] = { |
212 | [1] = {["isDefault"] = true, |
213 | ["name"] = g_i18n:getText("configuration_valueNo"), |
214 | ["index"] = 1, |
215 | ["dailyUpkeep"] = 0, |
216 | ["saveId"] = "1", |
217 | ["isSelectable"] = true, |
218 | ["price"] = 0, |
219 | ["nameCompareParams"] = {}, |
220 | }, |
221 | [2] = {["isDefault"] = false, |
222 | ["name"] = g_i18n:getText("configuration_valueYes"), |
223 | ["index"] = 2, |
224 | ["dailyUpkeep"] = 0, |
225 | ["saveId"] = "2", |
226 | ["isSelectable"] = true, |
227 | ["price"] = self.configurationPrice, |
228 | ["nameCompareParams"] = {}, |
229 | }, |
230 | } |
231 | end |
232 | |
233 | |
234 | return configurations, defaultConfigurationIds |
235 | end) |
236 | end |
240 | function CropSensorLinkageData:registerXMLPaths(schema) |
241 | schema:register(XMLValueType.STRING, "cropSensorLinkageData.sensors#filename", "Link to i3d filename containing the sensors") |
242 | schema:register(XMLValueType.STRING, "cropSensorLinkageData.sensors.sensor(?)#type", "Type of sensor (SENSOR_LEFT | SENSOR_RIGHT | SENSOR_TOP)") |
243 | schema:register(XMLValueType.NODE_INDEX, "cropSensorLinkageData.sensors.sensor(?)#node", "Path to sensor node") |
244 | schema:register(XMLValueType.STRING, "cropSensorLinkageData.sensors.sensor(?)#measurementNode", "Reference node for measuring") |
245 | schema:register(XMLValueType.BOOL, "cropSensorLinkageData.sensors.sensor(?)#requiresDaylight", "Sensor requires daylight", true) |
246 | schema:register(XMLValueType.STRING, "cropSensorLinkageData.sensors.sensor(?).rotationNode(?)#node", "Path to rotation node") |
247 | schema:register(XMLValueType.BOOL, "cropSensorLinkageData.sensors.sensor(?).rotationNode(?)#autoRotate", "Rotation will be automatically adjusted to the vehicle orientation", false) |
248 | |
249 | schema:register(XMLValueType.STRING, "cropSensorLinkageData.vehicles.vehicle(?)#filename", "Last part of vehicle filename") |
250 | schema:register(XMLValueType.STRING, "cropSensorLinkageData.vehicles.vehicle(?).linkNode(?)#node", "Name of node in i3d mapping") |
251 | schema:register(XMLValueType.STRING, "cropSensorLinkageData.vehicles.vehicle(?).linkNode(?)#type", "Type of node to link (SENSOR_LEFT | SENSOR_RIGHT | SENSOR_TOP)") |
252 | schema:register(XMLValueType.VECTOR_TRANS, "cropSensorLinkageData.vehicles.vehicle(?).linkNode(?)#translation", "Translation offset from node", "0 0 0") |
253 | schema:register(XMLValueType.VECTOR_ROT, "cropSensorLinkageData.vehicles.vehicle(?).linkNode(?)#rotation", "Rotation offset from node", "0 0 0") |
254 | schema:register(XMLValueType.BOOL, "cropSensorLinkageData.vehicles.vehicle(?).linkNode(?).rotationNode(?)#autoRotate", "Rotation will be automatically adjusted to the vehicle orientation") |
255 | schema:register(XMLValueType.VECTOR_ROT, "cropSensorLinkageData.vehicles.vehicle(?).linkNode(?).rotationNode(?)#rotation", "Rotation of rotation node", "0 0 0") |
256 | |
257 | schema:register(XMLValueType.FLOAT, "cropSensorLinkageData.configuration#price", "Price of crop sensor config", 0) |
258 | end |