Script v1_7_1_0
- AI
- Animals
- Collections
- Contracts
- Debug
- Economy
- Elements
- EnvironmentalScore
- Errors
- Events
- GUI
- Handtools
- Hud
- I3d
- Input
- Jobs
- Maps
- Materials
- Misc
- Objects
- Parameters
- Placeables
- Placement
- Player
- Shop
- Sounds
- Specialization
- Specializations
- StateMachine
- Statistics
- Tasks
- Triggers
- Utils
- Vehicles
Engine v1_7_1_0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- general
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- NoteNode
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- VoiceChat
- XML
Foundation Reference
FillUnit
DescriptionSpecialization for vehicles with any sort of capacity or tank. Manages filltypes, capacities, fillLevel changesFunctions
- actionEventConsoleFillUnitDec
- actionEventConsoleFillUnitInc
- actionEventConsoleFillUnitNext
- actionEventUnload
- addFillTypeSources
- addFillUnitFillLevel
- addFillUnitTrigger
- addNodeObjectMapping
- debugGetSupportedFillTypesPerFillUnit
- emptyAllFillUnits
- getAdditionalComponentMass
- getAlarmTriggerIsActive
- getAllowLoadTriggerActivation
- getCanBeTurnedOn
- getCapacityFromXml
- getDoConsumePtoPower
- getDrawFirstFillText
- getFillLevelInformation
- getFillTypeChangeThreshold
- getFillTypeNamesFromXML
- getFillUnitAllowsFillType
- getFillUnitAutoAimTargetNode
- getFillUnitByIndex
- getFillUnitCapacity
- getFillUnitExactFillRootNode
- getFillUnitExists
- getFillUnitExtraDistanceFromNode
- getFillUnitFillLevel
- getFillUnitFillLevelPercentage
- getFillUnitFillType
- getFillUnitFirstSupportedFillType
- getFillUnitForcedMaterialFillType
- getFillUnitFreeCapacity
- getFillUnitFromNode
- getFillUnitIndexFromNode
- getFillUnitLastValidFillType
- getFillUnitRootNode
- getFillUnits
- getFillUnitSupportedFillTypes
- getFillUnitSupportedToolTypes
- getFillUnitSupportsFillType
- getFillUnitSupportsToolType
- getFillUnitSupportsToolTypeAndFillType
- getFirstValidFillUnitToFill
- getIsFillAllowedFromFarm
- getIsFillUnitActive
- getIsFoldAllowed
- getIsLevelerPickupNodeActive
- getIsMovingToolActive
- getIsPowerTakeOffActive
- getIsReadyForAutomatedTrainTravel
- getSpecValueCapacity
- getSpecValueFillTypes
- getSpecValueStartFillUnitMassByMassData
- initSpecialization
- loadAlarmTrigger
- loadFillPlane
- loadFillTypeMaterials
- loadFillUnitFromXML
- loadFillUnitUnloadingFromXML
- loadLevelerNodeFromXML
- loadMeasurementNode
- loadMovingToolFromXML
- loadSpecValueCapacity
- loadSpecValueFillTypes
- loadSpecValueFillUnitMassData
- onDeactivate
- onDelete
- onDischargeTargetObjectChanged
- onDraw
- onLoad
- onPostLoad
- onReadStream
- onReadUpdateStream
- onRegisterActionEvents
- onUpdateTick
- onWriteStream
- onWriteUpdateStream
- prerequisitesPresent
- registerEventListeners
- registerEvents
- registerFunctions
- registerOverwrittenFunctions
- registerUnitDisplaySchema
- removeFillUnitTrigger
- removeNodeObjectMapping
- saveStatsToXMLFile
- saveToXMLFile
- setAlarmTriggerState
- setFillPlaneForcedFillType
- setFillSoundIsPlaying
- setFillUnitCapacity
- setFillUnitFillLevelToDisplay
- setFillUnitFillType
- setFillUnitFillTypeToDisplay
- setFillUnitForcedMaterialFillType
- setFillUnitIsFilling
- setFillUnitLastValidFillType
- showInfo
- unloadFillUnits
- updateAlarmTriggers
- updateFillTypeMaterials
- updateFillUnitAutoAimTarget
- updateFillUnitFillPlane
- updateFillUnitTriggers
- updateMeasurementNodes
- updateUnloadActionDisplay
actionEventConsoleFillUnitDec
DescriptionDefinitionactionEventConsoleFillUnitDec()Code
2879 | function FillUnit.actionEventConsoleFillUnitDec(self, actionName, inputValue, callbackState, isAnalog) |
2880 | if self:getIsSelected() then |
2881 | local fillType = self:getFillUnitFillType(1) |
2882 | self:addFillUnitFillLevel(self:getOwnerFarmId(), 1, -1000, fillType, ToolType.UNDEFINED, nil) |
2883 | end |
2884 | end |
actionEventConsoleFillUnitInc
DescriptionDefinitionactionEventConsoleFillUnitInc()Code
2866 | function FillUnit.actionEventConsoleFillUnitInc(self, actionName, inputValue, callbackState, isAnalog) |
2867 | if self:getIsSelected() then |
2868 | local fillType = self:getFillUnitFillType(1) |
2869 | if fillType == FillType.UNKNOWN then |
2870 | local fillUnit = self:getFillUnitByIndex(1) |
2871 | fillType = next(fillUnit.supportedFillTypes) |
2872 | end |
2873 | self:addFillUnitFillLevel(self:getOwnerFarmId(), 1, 1000, fillType, ToolType.UNDEFINED, nil) |
2874 | end |
2875 | end |
actionEventConsoleFillUnitNext
DescriptionDefinitionactionEventConsoleFillUnitNext()Code
2838 | function FillUnit.actionEventConsoleFillUnitNext(self, actionName, inputValue, callbackState, isAnalog) |
2839 | if self:getIsSelected() then |
2840 | local fillType = self:getFillUnitFillType(1) |
2841 | local fillUnit = self:getFillUnitByIndex(1) |
2842 | local found = false |
2843 | local nextFillType = nil |
2844 | for supportedFillType,_ in pairs(fillUnit.supportedFillTypes) do |
2845 | if not found then |
2846 | if supportedFillType == fillType then |
2847 | found = true |
2848 | end |
2849 | else |
2850 | nextFillType = supportedFillType |
2851 | break |
2852 | end |
2853 | end |
2854 | |
2855 | if nextFillType == nil then |
2856 | nextFillType = next(fillUnit.supportedFillTypes) |
2857 | end |
2858 | |
2859 | self:addFillUnitFillLevel(self:getOwnerFarmId(), 1, -math.huge, fillType, ToolType.UNDEFINED, nil) |
2860 | self:addFillUnitFillLevel(self:getOwnerFarmId(), 1, 100, nextFillType, ToolType.UNDEFINED, nil) |
2861 | end |
2862 | end |
actionEventUnload
DescriptionDefinitionactionEventUnload()Code
2888 | function FillUnit.actionEventUnload(self, actionName, inputValue, callbackState, isAnalog) |
2889 | self:unloadFillUnits() |
2890 | end |
addFillTypeSources
DescriptionDefinitionaddFillTypeSources()Code
2426 | function FillUnit.addFillTypeSources(sources, currentVehicle, excludeVehicle, fillTypes) |
2427 | if currentVehicle ~= excludeVehicle then |
2428 | local curVehicle = currentVehicle.spec_fillUnit |
2429 | if curVehicle ~= nil then |
2430 | for fillUnitIndex2, fillUnit2 in pairs(curVehicle.fillUnits) do |
2431 | for _,fillType in pairs(fillTypes) do |
2432 | if fillUnit2.supportedFillTypes[fillType] then |
2433 | if sources[fillType] == nil then |
2434 | sources[fillType] = {} |
2435 | end |
2436 | table.insert(sources[fillType], {vehicle=currentVehicle, fillUnitIndex=fillUnitIndex2}) |
2437 | end |
2438 | end |
2439 | end |
2440 | end |
2441 | end |
2442 | |
2443 | if currentVehicle.getAttachedImplements ~= nil then |
2444 | local attachedImplements = currentVehicle:getAttachedImplements() |
2445 | for _,implement in pairs(attachedImplements) do |
2446 | if implement.object ~= nil then |
2447 | FillUnit.addFillTypeSources(sources, implement.object, excludeVehicle, fillTypes) |
2448 | end |
2449 | end |
2450 | end |
2451 | end |
addFillUnitFillLevel
DescriptionDefinitionaddFillUnitFillLevel()Code
1282 | function FillUnit:addFillUnitFillLevel(farmId, fillUnitIndex, fillLevelDelta, fillTypeIndex, toolType, fillPositionData) |
1283 | local spec = self.spec_fillUnit |
1284 | spec.isInfoDirty = true |
1285 | |
1286 | -- Check for permission. Do allow vehicles with farmId 0 (all-access vehicles). |
1287 | -- Only check for access if value is being removed |
1288 | if fillLevelDelta < 0 and not g_currentMission.accessHandler:canFarmAccess(farmId, self, true) then |
1289 | return 0 |
1290 | end |
1291 | |
1292 | -- If this fillunit belongs to a mounted object (pallet), check that the controller of the object |
1293 | -- is allowed to empty the fill unit. |
1294 | if self.getMountObject ~= nil then |
1295 | local mounter = self:getDynamicMountObject() or self:getMountObject() |
1296 | if mounter ~= nil then |
1297 | -- if the active farm of the mounter has NO access to farmId fill unit: disallow |
1298 | if not g_currentMission.accessHandler:canFarmAccess(mounter:getActiveFarm(), self, true) then |
1299 | return 0 |
1300 | end |
1301 | end |
1302 | end |
1303 | |
1304 | local fillUnit = spec.fillUnits[fillUnitIndex] |
1305 | if fillUnit ~= nil then |
1306 | if fillLevelDelta > 0 then |
1307 | if not fillUnit.ignoreFillLimit then |
1308 | if g_currentMission.missionInfo.trailerFillLimit and self:getMaxComponentMassReached() then |
1309 | return 0 |
1310 | end |
1311 | end |
1312 | end |
1313 | |
1314 | if not self:getFillUnitSupportsToolTypeAndFillType(fillUnitIndex, toolType, fillTypeIndex) then |
1315 | return 0 |
1316 | end |
1317 | |
1318 | -- apply limit only on server side, client will receive the correct data |
1319 | if self.isServer then |
1320 | if fillLevelDelta > 0 then |
1321 | if not fillUnit.ignoreFillLimit then |
1322 | if g_currentMission.missionInfo.trailerFillLimit then |
1323 | local maxMassToApply = self:getAvailableComponentMass() |
1324 | local fillTypeDesc = g_fillTypeManager:getFillTypeByIndex(fillTypeIndex) |
1325 | if fillTypeDesc ~= nil then |
1326 | fillLevelDelta = math.min(fillLevelDelta, maxMassToApply / fillTypeDesc.massPerLiter) |
1327 | end |
1328 | end |
1329 | end |
1330 | end |
1331 | end |
1332 | |
1333 | local oldFillLevel = fillUnit.fillLevel |
1334 | local capacity = fillUnit.capacity |
1335 | if capacity == 0 then |
1336 | capacity = math.huge |
1337 | end |
1338 | |
1339 | local fillTypeChanged = false |
1340 | if fillUnit.fillType == fillTypeIndex then |
1341 | fillUnit.fillLevel = math.max(0, math.min(capacity, oldFillLevel + fillLevelDelta)) |
1342 | else |
1343 | if fillLevelDelta > 0 then |
1344 | local allowFillType = self:getFillUnitAllowsFillType(fillUnitIndex, fillTypeIndex) |
1345 | if allowFillType then |
1346 | local oldFillTypeIndex = fillUnit.fillType |
1347 | if oldFillLevel > 0 then |
1348 | self:addFillUnitFillLevel(farmId, fillUnitIndex, -math.huge, fillUnit.fillType, toolType, fillPositionData) |
1349 | end |
1350 | oldFillLevel = 0 |
1351 | fillUnit.fillLevel = math.max(0, math.min(capacity, fillLevelDelta)) |
1352 | fillUnit.fillType = fillTypeIndex |
1353 | |
1354 | fillTypeChanged = true |
1355 | self.rootVehicle:raiseStateChange(Vehicle.STATE_CHANGE_FILLTYPE_CHANGE) |
1356 | SpecializationUtil.raiseEvent(self, "onChangedFillType", fillUnitIndex, fillTypeIndex, oldFillTypeIndex) |
1357 | else |
1358 | return 0 |
1359 | end |
1360 | end |
1361 | end |
1362 | |
1363 | -- reset fill level if below threshold due to float 32 inaccuracy |
1364 | if fillUnit.fillLevel < 0.00001 then |
1365 | fillUnit.fillLevel = 0 |
1366 | end |
1367 | |
1368 | if fillUnit.fillLevel > 0 then |
1369 | fillUnit.lastValidFillType = fillUnit.fillType |
1370 | else |
1371 | SpecializationUtil.raiseEvent(self, "onChangedFillType", fillUnitIndex, FillType.UNKNOWN, fillUnit.fillType) |
1372 | fillUnit.fillType = FillType.UNKNOWN |
1373 | |
1374 | if not fillUnit.fillTypeToDisplayIsPersistent then |
1375 | fillUnit.fillTypeToDisplay = FillType.UNKNOWN |
1376 | end |
1377 | |
1378 | if not fillUnit.fillLevelToDisplayIsPersistent then |
1379 | fillUnit.fillLevelToDisplay = nil |
1380 | end |
1381 | end |
1382 | |
1383 | local appliedDelta = fillUnit.fillLevel - oldFillLevel |
1384 | |
1385 | if self.isServer then |
1386 | -- prepare for network |
1387 | if fillUnit.synchronizeFillLevel then |
1388 | local hasChanged = false |
1389 | if fillUnit.fillLevel ~= fillUnit.fillLevelSent then |
1390 | local maxValue = 2^fillUnit.synchronizationNumBits - 1 |
1391 | local levelPerBit = fillUnit.capacity / maxValue |
1392 | local changedLevel = math.abs(fillUnit.fillLevel - fillUnit.fillLevelSent) |
1393 | |
1394 | if changedLevel > levelPerBit then |
1395 | fillUnit.fillLevelSent = fillUnit.fillLevel |
1396 | hasChanged = true |
1397 | end |
1398 | end |
1399 | if fillUnit.fillType ~= fillUnit.fillTypeSent then |
1400 | fillUnit.fillTypeSent = fillUnit.fillType |
1401 | hasChanged = true |
1402 | end |
1403 | if fillUnit.lastValidFillType ~= fillUnit.lastValidFillTypeSent then |
1404 | fillUnit.lastValidFillTypeSent = fillUnit.lastValidFillType |
1405 | hasChanged = true |
1406 | end |
1407 | if hasChanged then |
1408 | self:raiseDirtyFlags(spec.dirtyFlag) |
1409 | end |
1410 | end |
1411 | end |
1412 | |
1413 | if fillUnit.updateMass then |
1414 | self:setMassDirty() |
1415 | end |
1416 | |
1417 | self:updateFillUnitAutoAimTarget(fillUnit) |
1418 | |
1419 | if self.isClient then |
1420 | self:updateAlarmTriggers(fillUnit.alarmTriggers) |
1421 | self:updateFillUnitFillPlane(fillUnit) |
1422 | self:updateMeasurementNodes(fillUnit, 0, true) |
1423 | |
1424 | if fillTypeChanged then |
1425 | self:updateFillTypeMaterials(fillUnit.fillTypeMaterials, fillUnit.fillType) |
1426 | end |
1427 | end |
1428 | |
1429 | SpecializationUtil.raiseEvent(self, "onFillUnitFillLevelChanged", fillUnitIndex, fillLevelDelta, fillTypeIndex, toolType, fillPositionData, appliedDelta) |
1430 | |
1431 | if self.isServer then |
1432 | if spec.removeVehicleIfEmpty and fillUnit.fillLevel <= 0.3 then |
1433 | if spec.removeVehicleDelay == 0 then |
1434 | g_currentMission:removeVehicle(self) |
1435 | else |
1436 | Timer.createOneshot(spec.removeVehicleDelay, function() |
1437 | g_currentMission:removeVehicle(self) |
1438 | end) |
1439 | end |
1440 | end |
1441 | end |
1442 | |
1443 | if appliedDelta > 0 then |
1444 | -- display default effects |
1445 | if #spec.fillEffects > 0 then |
1446 | g_effectManager:setFillType(spec.fillEffects, fillUnit.fillType) |
1447 | g_effectManager:startEffects(spec.fillEffects) |
1448 | |
1449 | spec.activeFillEffects[spec.fillEffects] = 500 |
1450 | end |
1451 | |
1452 | -- display fill unit effects |
1453 | if #fillUnit.fillEffects > 0 then |
1454 | g_effectManager:setFillType(fillUnit.fillEffects, fillUnit.fillType) |
1455 | g_effectManager:startEffects(fillUnit.fillEffects) |
1456 | |
1457 | spec.activeFillEffects[fillUnit.fillEffects] = 500 |
1458 | end |
1459 | |
1460 | |
1461 | -- start default animation nodes |
1462 | if #spec.animationNodes > 0 then |
1463 | g_animationManager:startAnimations(spec.animationNodes) |
1464 | spec.activeFillAnimations[spec.animationNodes] = 500 |
1465 | end |
1466 | |
1467 | -- start fill unit animation nodes |
1468 | if #fillUnit.animationNodes > 0 then |
1469 | g_animationManager:startAnimations(fillUnit.animationNodes) |
1470 | spec.activeFillAnimations[fillUnit.animationNodes] = 500 |
1471 | end |
1472 | |
1473 | if fillUnit.fillAnimation ~= nil then |
1474 | if fillUnit.fillAnimationLoadTime ~= nil then |
1475 | local animTime = self:getAnimationTime(fillUnit.fillAnimation) |
1476 | local direction = MathUtil.sign(fillUnit.fillAnimationLoadTime-animTime) |
1477 | if direction ~= 0 then |
1478 | self:playAnimation(fillUnit.fillAnimation, direction, animTime) |
1479 | self:setAnimationStopTime(fillUnit.fillAnimation, fillUnit.fillAnimationLoadTime) |
1480 | end |
1481 | end |
1482 | end |
1483 | end |
1484 | |
1485 | if appliedDelta ~= 0 then |
1486 | if fillUnit.fillLevelAnimationName ~= nil then |
1487 | if fillUnit.fillLevel > 0 or fillUnit.fillLevelAnimationResetOnEmpty then |
1488 | local targetTime = fillUnit.fillLevel / fillUnit.capacity |
1489 | local direction = 1 |
1490 | if targetTime < self:getAnimationTime(fillUnit.fillLevelAnimationName) then |
1491 | direction = -1 |
1492 | end |
1493 | self:playAnimation(fillUnit.fillLevelAnimationName, direction, self:getAnimationTime(fillUnit.fillLevelAnimationName), true) |
1494 | self:setAnimationStopTime(fillUnit.fillLevelAnimationName, targetTime) |
1495 | end |
1496 | end |
1497 | end |
1498 | |
1499 | if fillUnit.fillLevel < 0.0001 then |
1500 | if fillUnit.fillAnimation ~= nil then |
1501 | if fillUnit.fillAnimationEmptyTime ~= nil then |
1502 | local animTime = self:getAnimationTime(fillUnit.fillAnimation) |
1503 | local direction = MathUtil.sign(fillUnit.fillAnimationEmptyTime-animTime) |
1504 | self:playAnimation(fillUnit.fillAnimation, direction, animTime) |
1505 | self:setAnimationStopTime(fillUnit.fillAnimation, fillUnit.fillAnimationEmptyTime) |
1506 | end |
1507 | end |
1508 | end |
1509 | |
1510 | if self.setDashboardsDirty ~= nil then |
1511 | self:setDashboardsDirty() |
1512 | end |
1513 | |
1514 | FillUnit.updateUnloadActionDisplay(self) |
1515 | |
1516 | return appliedDelta |
1517 | end |
1518 | |
1519 | return 0 |
1520 | end |
addFillUnitTrigger
DescriptionAdds fill triggerDefinition
addFillUnitTrigger(table trigger, integer fillTypeIndex)Arguments
table | trigger | trigger |
integer | fillTypeIndex | fillTypeIndex |
2023 | function FillUnit:addFillUnitTrigger(trigger, fillTypeIndex, fillUnitIndex) |
2024 | local spec = self.spec_fillUnit |
2025 | if #spec.fillTrigger.triggers == 0 then |
2026 | g_currentMission.activatableObjectsSystem:addActivatable(spec.fillTrigger.activatable) |
2027 | spec.fillTrigger.activatable:setFillType(fillTypeIndex) |
2028 | |
2029 | -- automatic filling for mobile version |
2030 | if self.isServer and Platform.gameplay.automaticFilling then |
2031 | self:setFillUnitIsFilling(true) |
2032 | end |
2033 | end |
2034 | table.addElement(spec.fillTrigger.triggers, trigger) |
2035 | SpecializationUtil.raiseEvent(self, "onAddedFillUnitTrigger", fillTypeIndex, fillUnitIndex, #spec.fillTrigger.triggers) |
2036 | |
2037 | self:updateFillUnitTriggers() |
2038 | end |
addNodeObjectMapping
DescriptionDefinitionaddNodeObjectMapping()Code
2182 | function FillUnit:addNodeObjectMapping(superFunc, list) |
2183 | superFunc(self, list) |
2184 | |
2185 | local spec = self.spec_fillUnit |
2186 | |
2187 | for _,fillUnit in pairs(spec.fillUnits) do |
2188 | if fillUnit.fillRootNode ~= nil then |
2189 | list[fillUnit.fillRootNode] = self |
2190 | end |
2191 | if fillUnit.exactFillRootNode ~= nil then |
2192 | list[fillUnit.exactFillRootNode] = self |
2193 | end |
2194 | end |
2195 | end |
debugGetSupportedFillTypesPerFillUnit
DescriptionReturns table with key=fillUnitIndex and value=array of fillTypeIdsDefinition
debugGetSupportedFillTypesPerFillUnit()Code
2416 | function FillUnit:debugGetSupportedFillTypesPerFillUnit() |
2417 | local fillUnitToFillTypes = {} |
2418 | for _, fillUnit in ipairs(self:getFillUnits()) do |
2419 | fillUnitToFillTypes[fillUnit.fillUnitIndex] = fillUnit.supportedFillTypes |
2420 | end |
2421 | return fillUnitToFillTypes |
2422 | end |
emptyAllFillUnits
DescriptionDefinitionemptyAllFillUnits()Code
1138 | function FillUnit:emptyAllFillUnits(ignoreDeleteOnEmptyFlag) |
1139 | local spec = self.spec_fillUnit |
1140 | local oldRemoveOnEmpty = spec.removeVehicleIfEmpty |
1141 | if ignoreDeleteOnEmptyFlag then |
1142 | spec.removeVehicleIfEmpty = false |
1143 | end |
1144 | |
1145 | for k, _ in ipairs(self:getFillUnits()) do |
1146 | local fillTypeIndex = self:getFillUnitFillType(k) |
1147 | self:addFillUnitFillLevel(self:getOwnerFarmId(), k, -math.huge, fillTypeIndex, ToolType.UNDEFINED, nil) |
1148 | end |
1149 | |
1150 | spec.removeVehicleIfEmpty = oldRemoveOnEmpty |
1151 | end |
getAdditionalComponentMass
DescriptionDefinitiongetAdditionalComponentMass()Code
2165 | function FillUnit:getAdditionalComponentMass(superFunc, component) |
2166 | local additionalMass = superFunc(self, component) |
2167 | local spec = self.spec_fillUnit |
2168 | |
2169 | for _, fillUnit in ipairs(spec.fillUnits) do |
2170 | if fillUnit.updateMass and fillUnit.fillMassNode == component.node and fillUnit.fillType ~= nil and fillUnit.fillType ~= FillType.UNKNOWN then |
2171 | local desc = g_fillTypeManager:getFillTypeByIndex(fillUnit.fillType) |
2172 | local mass = fillUnit.fillLevel * desc.massPerLiter |
2173 | additionalMass = additionalMass + mass |
2174 | end |
2175 | end |
2176 | |
2177 | return additionalMass |
2178 | end |
getAlarmTriggerIsActive
DescriptionDefinitiongetAlarmTriggerIsActive()Code
1076 | function FillUnit:getAlarmTriggerIsActive(alarmTrigger) |
1077 | local ret = false |
1078 | |
1079 | local fillLevelPct = alarmTrigger.fillUnit.fillLevel / alarmTrigger.fillUnit.capacity |
1080 | if fillLevelPct >= alarmTrigger.minFillLevel and fillLevelPct <= alarmTrigger.maxFillLevel then |
1081 | ret = true |
1082 | end |
1083 | |
1084 | return ret |
1085 | end |
getAllowLoadTriggerActivation
DescriptionDefinitiongetAllowLoadTriggerActivation()Code
1165 | function FillUnit:getAllowLoadTriggerActivation(rootVehicle) |
1166 | if self.rootVehicle == g_currentMission.controlledVehicle then |
1167 | return true |
1168 | end |
1169 | |
1170 | return false |
1171 | end |
getCanBeTurnedOn
DescriptionDefinitiongetCanBeTurnedOn()Code
2335 | function FillUnit:getCanBeTurnedOn(superFunc) |
2336 | local spec = self.spec_fillUnit |
2337 | |
2338 | for _, alarmTrigger in pairs(spec.activeAlarmTriggers) do |
2339 | if alarmTrigger.turnOffInTrigger then |
2340 | return false |
2341 | end |
2342 | end |
2343 | |
2344 | return superFunc(self) |
2345 | end |
getCapacityFromXml
DescriptionDefinitiongetCapacityFromXml()Code
2605 | function FillUnit.getCapacityFromXml(xmlFile) |
2606 | local rootName = xmlFile:getRootName() |
2607 | local maxCapacity = 0 |
2608 | |
2609 | xmlFile:iterate(rootName..".fillUnit.fillUnitConfigurations.fillUnitConfiguration",function(_, key) |
2610 | xmlFile:iterate(key..".fillUnits.fillUnit", function(_, fillUnitKey) |
2611 | maxCapacity = math.max(maxCapacity, xmlFile:getValue(fillUnitKey .. "#capacity") or 0) |
2612 | end) |
2613 | end) |
2614 | |
2615 | return maxCapacity |
2616 | end |
getDoConsumePtoPower
DescriptionDefinitiongetDoConsumePtoPower()Code
2321 | function FillUnit:getDoConsumePtoPower(superFunc) |
2322 | local fillTrigger = self.spec_fillUnit.fillTrigger |
2323 | return superFunc(self) or (fillTrigger.isFilling and fillTrigger.consumePtoPower) |
2324 | end |
getDrawFirstFillText
DescriptionDefinitiongetDrawFirstFillText()Code
761 | function FillUnit:getDrawFirstFillText() |
762 | return false |
763 | end |
getFillLevelInformation
DescriptionGet fill level informationDefinition
getFillLevelInformation(table fillLevelInformations)Arguments
table | fillLevelInformations | fill level informations |
2219 | function FillUnit:getFillLevelInformation(superFunc, display) |
2220 | superFunc(self, display) |
2221 | |
2222 | local spec = self.spec_fillUnit |
2223 | for i=1, #spec.fillUnits do |
2224 | local fillUnit = spec.fillUnits[i] |
2225 | if fillUnit.capacity > 0 and fillUnit.showOnHud then |
2226 | local fillType = fillUnit.fillType |
2227 | |
2228 | -- if we only support one fill type and are empty we show the fill type |
2229 | if fillType == FillType.UNKNOWN then |
2230 | if table.size(fillUnit.supportedFillTypes) == 1 then |
2231 | fillType = next(fillUnit.supportedFillTypes) |
2232 | end |
2233 | end |
2234 | |
2235 | if fillUnit.fillTypeToDisplay ~= FillType.UNKNOWN then |
2236 | fillType = fillUnit.fillTypeToDisplay |
2237 | end |
2238 | |
2239 | local fillLevel = fillUnit.fillLevel |
2240 | if fillUnit.fillLevelToDisplay ~= nil then |
2241 | fillLevel = fillUnit.fillLevelToDisplay |
2242 | end |
2243 | |
2244 | -- child and parent units will be merged together as display if one of them has a valid fill type and another an unknown fill type |
2245 | -- capacity is used from the parent one |
2246 | local capacity = fillUnit.capacity |
2247 | if fillUnit.parentUnitOnHud ~= nil then |
2248 | if fillType == FillType.UNKNOWN then |
2249 | fillType = spec.fillUnits[fillUnit.parentUnitOnHud].fillType |
2250 | end |
2251 | capacity = 0 |
2252 | elseif fillUnit.childUnitOnHud ~= nil then |
2253 | if fillType == FillType.UNKNOWN then |
2254 | fillType = spec.fillUnits[fillUnit.childUnitOnHud].fillType |
2255 | end |
2256 | end |
2257 | |
2258 | local maxReached = not fillUnit.ignoreFillLimit and g_currentMission.missionInfo.trailerFillLimit and self:getMaxComponentMassReached() |
2259 | display:addFillLevel(fillType, fillLevel, capacity, fillLevel > 0 and fillUnit.uiPrecision or 0, maxReached) |
2260 | end |
2261 | end |
2262 | end |
getFillTypeChangeThreshold
DescriptionDefinitiongetFillTypeChangeThreshold()Code
972 | function FillUnit:getFillTypeChangeThreshold(fillUnitIndex) |
973 | if fillUnitIndex == nil then |
974 | return self.spec_fillUnit.fillTypeChangeThreshold |
975 | else |
976 | local capacity = self:getFillUnitCapacity(fillUnitIndex) or 1 |
977 | return capacity * self.spec_fillUnit.fillTypeChangeThreshold |
978 | end |
979 | end |
getFillTypeNamesFromXML
DescriptionDefinitiongetFillTypeNamesFromXML()Code
2698 | function FillUnit.getFillTypeNamesFromXML(xmlFile) |
2699 | local fillTypeNames = nil |
2700 | local fillTypeCategoryNames = nil |
2701 | local rootName = xmlFile:getRootName() |
2702 | |
2703 | xmlFile:iterate(rootName..".fillUnit.fillUnitConfigurations.fillUnitConfiguration",function(_, key) |
2704 | xmlFile:iterate(key..".fillUnits.fillUnit", function(_, fillUnitKey) |
2705 | local capacity = xmlFile:getValue(fillUnitKey.."#capacity") |
2706 | if capacity == nil or capacity > 0 then |
2707 | local currentFillTypes = xmlFile:getValue(fillUnitKey .. "#fillTypes") |
2708 | if currentFillTypes ~= nil then |
2709 | if fillTypeNames == nil then |
2710 | fillTypeNames = currentFillTypes |
2711 | else |
2712 | fillTypeNames = fillTypeNames .. " " .. currentFillTypes |
2713 | end |
2714 | end |
2715 | |
2716 | local currentFillTypeCategories = xmlFile:getValue(fillUnitKey .. "#fillTypeCategories") |
2717 | if currentFillTypeCategories ~= nil then |
2718 | if fillTypeCategoryNames == nil then |
2719 | fillTypeCategoryNames = currentFillTypeCategories |
2720 | else |
2721 | fillTypeCategoryNames = fillTypeCategoryNames .. " " .. currentFillTypeCategories |
2722 | end |
2723 | end |
2724 | end |
2725 | end) |
2726 | end) |
2727 | |
2728 | return {fillTypeNames=fillTypeNames, fillTypeCategoryNames=fillTypeCategoryNames} |
2729 | end |
getFillUnitAllowsFillType
DescriptionDefinitiongetFillUnitAllowsFillType()Code
956 | function FillUnit:getFillUnitAllowsFillType(fillUnitIndex, fillType) |
957 | local spec = self.spec_fillUnit |
958 | if spec.fillUnits[fillUnitIndex] ~= nil then |
959 | if self:getFillUnitSupportsFillType(fillUnitIndex, fillType) then |
960 | if fillType == spec.fillUnits[fillUnitIndex].fillType then |
961 | return true |
962 | else |
963 | return (spec.fillUnits[fillUnitIndex].fillLevel / math.max(spec.fillUnits[fillUnitIndex].capacity, 0.0001)) <= self:getFillTypeChangeThreshold() |
964 | end |
965 | end |
966 | end |
967 | return false |
968 | end |
getFillUnitAutoAimTargetNode
DescriptionDefinitiongetFillUnitAutoAimTargetNode()Code
899 | function FillUnit:getFillUnitAutoAimTargetNode(fillUnitIndex) |
900 | local spec = self.spec_fillUnit |
901 | if spec.fillUnits[fillUnitIndex] ~= nil then |
902 | return spec.fillUnits[fillUnitIndex].autoAimTarget.node |
903 | end |
904 | return nil |
905 | end |
getFillUnitByIndex
DescriptionDefinitiongetFillUnitByIndex()Code
774 | function FillUnit:getFillUnitByIndex(fillUnitIndex) |
775 | local spec = self.spec_fillUnit |
776 | if self:getFillUnitExists(fillUnitIndex) then |
777 | return spec.fillUnits[fillUnitIndex] |
778 | end |
779 | return nil |
780 | end |
getFillUnitCapacity
DescriptionDefinitiongetFillUnitCapacity()Code
791 | function FillUnit:getFillUnitCapacity(fillUnitIndex) |
792 | local spec = self.spec_fillUnit |
793 | if spec.fillUnits[fillUnitIndex] ~= nil then |
794 | return spec.fillUnits[fillUnitIndex].capacity |
795 | end |
796 | return nil |
797 | end |
getFillUnitExactFillRootNode
DescriptionDefinitiongetFillUnitExactFillRootNode()Code
879 | function FillUnit:getFillUnitExactFillRootNode(fillUnitIndex) |
880 | local spec = self.spec_fillUnit |
881 | if spec.fillUnits[fillUnitIndex] ~= nil then |
882 | return spec.fillUnits[fillUnitIndex].exactFillRootNode |
883 | end |
884 | return nil |
885 | end |
getFillUnitExists
DescriptionDefinitiongetFillUnitExists()Code
784 | function FillUnit:getFillUnitExists(fillUnitIndex) |
785 | local spec = self.spec_fillUnit |
786 | return fillUnitIndex ~= nil and spec.fillUnits[fillUnitIndex] ~= nil |
787 | end |
getFillUnitExtraDistanceFromNode
DescriptionDefinitiongetFillUnitExtraDistanceFromNode()Code
1124 | function FillUnit:getFillUnitExtraDistanceFromNode(node) |
1125 | local spec = self.spec_fillUnit |
1126 | return spec.exactFillRootNodeToExtraDistance[node] or 0 |
1127 | end |
getFillUnitFillLevel
DescriptionDefinitiongetFillUnitFillLevel()Code
829 | function FillUnit:getFillUnitFillLevel(fillUnitIndex) |
830 | local spec = self.spec_fillUnit |
831 | if spec.fillUnits[fillUnitIndex] ~= nil then |
832 | return spec.fillUnits[fillUnitIndex].fillLevel |
833 | end |
834 | return nil |
835 | end |
getFillUnitFillLevelPercentage
DescriptionDefinitiongetFillUnitFillLevelPercentage()Code
839 | function FillUnit:getFillUnitFillLevelPercentage(fillUnitIndex) |
840 | local spec = self.spec_fillUnit |
841 | if spec.fillUnits[fillUnitIndex] ~= nil then |
842 | return spec.fillUnits[fillUnitIndex].fillLevel / spec.fillUnits[fillUnitIndex].capacity |
843 | end |
844 | return nil |
845 | end |
getFillUnitFillType
DescriptionDefinitiongetFillUnitFillType()Code
849 | function FillUnit:getFillUnitFillType(fillUnitIndex) |
850 | local spec = self.spec_fillUnit |
851 | if spec.fillUnits[fillUnitIndex] ~= nil then |
852 | return spec.fillUnits[fillUnitIndex].fillType |
853 | end |
854 | return nil |
855 | end |
getFillUnitFirstSupportedFillType
DescriptionDefinitiongetFillUnitFirstSupportedFillType()Code
869 | function FillUnit:getFillUnitFirstSupportedFillType(fillUnitIndex) |
870 | local spec = self.spec_fillUnit |
871 | if spec.fillUnits[fillUnitIndex] ~= nil then |
872 | return next(spec.fillUnits[fillUnitIndex].supportedFillTypes) |
873 | end |
874 | return nil |
875 | end |
getFillUnitForcedMaterialFillType
DescriptionDefinitiongetFillUnitForcedMaterialFillType()Code
1057 | function FillUnit:getFillUnitForcedMaterialFillType(fillUnitIndex) |
1058 | local spec = self.spec_fillUnit |
1059 | if spec.fillUnits[fillUnitIndex] ~= nil then |
1060 | return spec.fillUnits[fillUnitIndex].forcedMaterialFillType |
1061 | end |
1062 | |
1063 | return FillType.UNKNOWN |
1064 | end |
getFillUnitFreeCapacity
DescriptiongetFillUnitFreeCapacityDefinition
getFillUnitFreeCapacity(Integer fillUnitIndex, Integer fillTypeIndex, Integer farmId)Arguments
Integer | fillUnitIndex | |
Integer | fillTypeIndex | currently ignored/unused |
Integer | farmId | currently ignored/unused |
804 | function FillUnit:getFillUnitFreeCapacity(fillUnitIndex, fillTypeIndex, farmId) |
805 | local spec = self.spec_fillUnit |
806 | local fillUnit = spec.fillUnits[fillUnitIndex] |
807 | if fillUnit ~= nil then |
808 | local freeCapacity = fillUnit.capacity - fillUnit.fillLevel |
809 | |
810 | if not fillUnit.ignoreFillLimit then |
811 | if g_currentMission.missionInfo.trailerFillLimit and self:getMaxComponentMassReached() then |
812 | return 0 |
813 | end |
814 | end |
815 | |
816 | return freeCapacity |
817 | end |
818 | return nil |
819 | end |
getFillUnitFromNode
DescriptionDefinitiongetFillUnitFromNode()Code
1131 | function FillUnit:getFillUnitFromNode(node) |
1132 | local spec = self.spec_fillUnit |
1133 | return spec.exactFillRootNodeToFillUnit[node] |
1134 | end |
getFillUnitIndexFromNode
DescriptionDefinitiongetFillUnitIndexFromNode()Code
1112 | function FillUnit:getFillUnitIndexFromNode(node) |
1113 | local spec = self.spec_fillUnit |
1114 | local fillUnit = spec.exactFillRootNodeToFillUnit[node] |
1115 | if fillUnit ~= nil then |
1116 | return fillUnit.fillUnitIndex |
1117 | end |
1118 | |
1119 | return nil |
1120 | end |
getFillUnitLastValidFillType
DescriptionDefinitiongetFillUnitLastValidFillType()Code
859 | function FillUnit:getFillUnitLastValidFillType(fillUnitIndex) |
860 | local spec = self.spec_fillUnit |
861 | if spec.fillUnits[fillUnitIndex] ~= nil then |
862 | return spec.fillUnits[fillUnitIndex].lastValidFillType |
863 | end |
864 | return nil |
865 | end |
getFillUnitRootNode
DescriptionDefinitiongetFillUnitRootNode()Code
889 | function FillUnit:getFillUnitRootNode(fillUnitIndex) |
890 | local spec = self.spec_fillUnit |
891 | if spec.fillUnits[fillUnitIndex] ~= nil then |
892 | return spec.fillUnits[fillUnitIndex].fillRootNode |
893 | end |
894 | return nil |
895 | end |
getFillUnits
DescriptionDefinitiongetFillUnits()Code
767 | function FillUnit:getFillUnits() |
768 | local spec = self.spec_fillUnit |
769 | return spec.fillUnits |
770 | end |
getFillUnitSupportedFillTypes
DescriptionDefinitiongetFillUnitSupportedFillTypes()Code
936 | function FillUnit:getFillUnitSupportedFillTypes(fillUnitIndex) |
937 | local spec = self.spec_fillUnit |
938 | if spec.fillUnits[fillUnitIndex] ~= nil then |
939 | return spec.fillUnits[fillUnitIndex].supportedFillTypes |
940 | end |
941 | return nil |
942 | end |
getFillUnitSupportedToolTypes
DescriptionDefinitiongetFillUnitSupportedToolTypes()Code
946 | function FillUnit:getFillUnitSupportedToolTypes(fillUnitIndex) |
947 | local spec = self.spec_fillUnit |
948 | if spec.fillUnits[fillUnitIndex] ~= nil then |
949 | return spec.fillUnits[fillUnitIndex].supportedToolTypes |
950 | end |
951 | return nil |
952 | end |
getFillUnitSupportsFillType
DescriptionDefinitiongetFillUnitSupportsFillType()Code
909 | function FillUnit:getFillUnitSupportsFillType(fillUnitIndex, fillType) |
910 | local spec = self.spec_fillUnit |
911 | if spec.fillUnits[fillUnitIndex] ~= nil then |
912 | return spec.fillUnits[fillUnitIndex].supportedFillTypes[fillType] |
913 | end |
914 | return false |
915 | end |
getFillUnitSupportsToolType
DescriptionDefinitiongetFillUnitSupportsToolType()Code
919 | function FillUnit:getFillUnitSupportsToolType(fillUnitIndex, toolType) |
920 | local spec = self.spec_fillUnit |
921 | if spec.fillUnits[fillUnitIndex] ~= nil then |
922 | return spec.fillUnits[fillUnitIndex].supportedToolTypes[toolType] |
923 | end |
924 | return false |
925 | end |
getFillUnitSupportsToolTypeAndFillType
DescriptionDefinitiongetFillUnitSupportsToolTypeAndFillType()Code
929 | function FillUnit:getFillUnitSupportsToolTypeAndFillType(fillUnitIndex, toolType, fillType) |
930 | return self:getFillUnitSupportsToolType(fillUnitIndex, toolType) |
931 | and self:getFillUnitSupportsFillType(fillUnitIndex, fillType) |
932 | end |
getFirstValidFillUnitToFill
DescriptionDefinitiongetFirstValidFillUnitToFill()Code
983 | function FillUnit:getFirstValidFillUnitToFill(fillType, ignoreCapacity) |
984 | local spec = self.spec_fillUnit |
985 | for fillUnitIndex, _ in ipairs(spec.fillUnits) do |
986 | if self:getFillUnitAllowsFillType(fillUnitIndex, fillType) then |
987 | if self:getFillUnitFreeCapacity(fillUnitIndex) > 0 or (ignoreCapacity ~= nil and ignoreCapacity) then |
988 | return fillUnitIndex |
989 | end |
990 | end |
991 | end |
992 | |
993 | return nil |
994 | end |
getIsFillAllowedFromFarm
DescriptionDefinitiongetIsFillAllowedFromFarm()Code
823 | function FillUnit:getIsFillAllowedFromFarm(farmId) |
824 | return true |
825 | end |
getIsFillUnitActive
DescriptionDefinitiongetIsFillUnitActive()Code
2157 | function FillUnit:getIsFillUnitActive(fillUnitIndex) |
2158 | return true |
2159 | end |
getIsFoldAllowed
DescriptionDefinitiongetIsFoldAllowed()Code
2266 | function FillUnit:getIsFoldAllowed(superFunc, direction, onAiTurnOn) |
2267 | local spec = self.spec_fillUnit |
2268 | if not spec.allowFoldingWhileFilled then |
2269 | for fillUnitIndex, _ in ipairs(spec.fillUnits) do |
2270 | if self:getFillUnitFillLevel(fillUnitIndex) > spec.allowFoldingThreshold then |
2271 | return false, spec.texts.warningFoldingFilled |
2272 | end |
2273 | end |
2274 | end |
2275 | |
2276 | return superFunc(self, direction, onAiTurnOn) |
2277 | end |
getIsLevelerPickupNodeActive
DescriptionDefinitiongetIsLevelerPickupNodeActive()Code
2405 | function FillUnit:getIsLevelerPickupNodeActive(superFunc, levelerNode) |
2406 | local fillLevelPct = self:getFillUnitFillLevelPercentage(levelerNode.limitFillUnitIndex) |
2407 | if fillLevelPct < levelerNode.minFillLevel or fillLevelPct > levelerNode.maxFillLevel then |
2408 | return false |
2409 | end |
2410 | |
2411 | return superFunc(self, levelerNode) |
2412 | end |
getIsMovingToolActive
DescriptionDefinitiongetIsMovingToolActive()Code
2308 | function FillUnit:getIsMovingToolActive(superFunc, movingTool) |
2309 | if movingTool.fillUnitIndex ~= nil then |
2310 | local fillLevelPct = self:getFillUnitFillLevelPercentage(movingTool.fillUnitIndex) |
2311 | if fillLevelPct > movingTool.minFillLevel or fillLevelPct < movingTool.maxFillLevel then |
2312 | return false |
2313 | end |
2314 | end |
2315 | |
2316 | return superFunc(self, movingTool) |
2317 | end |
getIsPowerTakeOffActive
DescriptionDefinitiongetIsPowerTakeOffActive()Code
2328 | function FillUnit:getIsPowerTakeOffActive(superFunc) |
2329 | local fillTrigger = self.spec_fillUnit.fillTrigger |
2330 | return superFunc(self) or (fillTrigger.isFilling and fillTrigger.consumePtoPower) |
2331 | end |
getIsReadyForAutomatedTrainTravel
DescriptionDefinitiongetIsReadyForAutomatedTrainTravel()Code
2281 | function FillUnit:getIsReadyForAutomatedTrainTravel(superFunc) |
2282 | local spec = self.spec_fillUnit |
2283 | for _, fillUnit in ipairs(spec.fillUnits) do |
2284 | if fillUnit.blocksAutomatedTrainTravel and fillUnit.fillLevel > 0 then |
2285 | return false |
2286 | end |
2287 | end |
2288 | |
2289 | return superFunc(self) |
2290 | end |
getSpecValueCapacity
DescriptionDefinitiongetSpecValueCapacity()Code
2516 | function FillUnit.getSpecValueCapacity(storeItem, realItem, configurations, saleItem, returnValues, returnRange) |
2517 | local configurationIndex = 1 |
2518 | if realItem ~= nil and storeItem.configurations ~= nil and realItem.configurations["fillUnit"] ~= nil and storeItem.configurations["fillUnit"] ~= nil then |
2519 | configurationIndex = realItem.configurations["fillUnit"] |
2520 | elseif configurations ~= nil and storeItem.configurations ~= nil and configurations["fillUnit"] ~= nil and storeItem.configurations["fillUnit"] ~= nil then |
2521 | configurationIndex = configurations["fillUnit"] |
2522 | end |
2523 | |
2524 | local minCapacity = 0 |
2525 | local capacity = 0 |
2526 | local unit = "" |
2527 | |
2528 | local fillUnitConfigurations = storeItem.specs.capacity |
2529 | if fillUnitConfigurations ~= nil then |
2530 | if realItem ~= nil or (configurations ~= nil and saleItem ~= nil) then |
2531 | if fillUnitConfigurations[configurationIndex] ~= nil then |
2532 | for _, fillUnit in ipairs(fillUnitConfigurations[configurationIndex]) do |
2533 | if realItem ~= nil and realItem.getFillUnitCapacity ~= nil and fillUnit.fillUnitIndex ~= nil then |
2534 | local unitCapacity = realItem:getFillUnitCapacity(fillUnit.fillUnitIndex) |
2535 | if unitCapacity ~= 0 and unitCapacity ~= math.huge then |
2536 | if fillUnit.conversionFunc ~= nil then |
2537 | unitCapacity = fillUnit.conversionFunc(unitCapacity) |
2538 | end |
2539 | capacity = capacity + unitCapacity |
2540 | end |
2541 | else |
2542 | capacity = capacity + fillUnit.capacity |
2543 | end |
2544 | |
2545 | unit = fillUnit.unit |
2546 | end |
2547 | minCapacity = capacity |
2548 | end |
2549 | else |
2550 | -- if no configuration index is given we use the max capacity the vehicle can have |
2551 | minCapacity = math.huge |
2552 | capacity = 0 |
2553 | for _, configuration in ipairs(fillUnitConfigurations) do |
2554 | local configCapacity = 0 |
2555 | for _, fillUnit in ipairs(configuration) do |
2556 | configCapacity = configCapacity + fillUnit.capacity |
2557 | unit = fillUnit.unit |
2558 | end |
2559 | |
2560 | if configCapacity ~= 0 then |
2561 | minCapacity = math.min(minCapacity, configCapacity) |
2562 | capacity = math.max(capacity, configCapacity) |
2563 | end |
2564 | end |
2565 | |
2566 | if minCapacity == capacity then |
2567 | capacity = minCapacity |
2568 | else |
2569 | if minCapacity ~= math.huge and capacity ~= 0 then |
2570 | if returnValues == nil or not returnValues then |
2571 | -- while allowed to return a string we return capacity range |
2572 | capacity = string.format("%s-%s", minCapacity, capacity) |
2573 | end |
2574 | end |
2575 | end |
2576 | end |
2577 | end |
2578 | |
2579 | if type(capacity) == "number" and capacity == 0 then |
2580 | if returnValues == nil or not returnValues then |
2581 | return nil |
2582 | end |
2583 | end |
2584 | |
2585 | if unit ~= "" then |
2586 | if unit:sub(1,6) == "$l10n_" then |
2587 | unit = unit:sub(7) |
2588 | end |
2589 | end |
2590 | |
2591 | if returnValues == nil or not returnValues then |
2592 | return string.format(g_i18n:getText("shop_capacityValue"), capacity, g_i18n:getText(unit or "unit_literShort")) |
2593 | else |
2594 | if returnRange == true and capacity ~= minCapacity then |
2595 | return minCapacity, capacity, unit |
2596 | else |
2597 | return minCapacity, unit |
2598 | end |
2599 | end |
2600 | end |
getSpecValueFillTypes
DescriptionDefinitiongetSpecValueFillTypes()Code
2733 | function FillUnit.getSpecValueFillTypes(storeItem, realItem, configurations) |
2734 | local specs = storeItem.specs.fillTypes |
2735 | if specs ~= nil then |
2736 | local configuration |
2737 | if configurations ~= nil then |
2738 | local configId = configurations["fillUnit"] |
2739 | configuration = specs.fillTypesByConfiguration[configId] |
2740 | end |
2741 | |
2742 | local categoryNames = specs.categoryNames |
2743 | if configuration ~= nil then |
2744 | categoryNames = configuration.categoryNames or categoryNames |
2745 | end |
2746 | |
2747 | local fillTypeNames = specs.fillTypeNames |
2748 | if configuration ~= nil then |
2749 | fillTypeNames = configuration.fillTypeNames or fillTypeNames |
2750 | end |
2751 | |
2752 | if categoryNames ~= nil or fillTypeNames ~= nil then |
2753 | local fillTypes = {} |
2754 | if categoryNames ~= nil then |
2755 | g_fillTypeManager:getFillTypesByCategoryNames(categoryNames, nil, fillTypes) |
2756 | end |
2757 | if fillTypeNames ~= nil then |
2758 | g_fillTypeManager:getFillTypesByNames(fillTypeNames, nil, fillTypes) |
2759 | end |
2760 | |
2761 | return fillTypes |
2762 | elseif specs.fruitTypeNames ~= nil then |
2763 | return g_fruitTypeManager:getFillTypesByFruitTypeNames(specs.fruitTypeNames, nil) |
2764 | elseif specs.fruitTypeCategoryNames ~= nil then |
2765 | if specs.useWindrowed then |
2766 | local fruitTypes = g_fruitTypeManager:getFruitTypesByCategoryNames(specs.fruitTypeCategoryNames, "Warning: Cutter has invalid fruitTypeCategory '%s'.") |
2767 | local windrowFillTypes = {} |
2768 | |
2769 | for _, fruitType in pairs(fruitTypes) do |
2770 | table.insert(windrowFillTypes, g_fruitTypeManager:getWindrowFillTypeIndexByFruitTypeIndex(fruitType)) |
2771 | end |
2772 | |
2773 | return windrowFillTypes |
2774 | else |
2775 | return g_fruitTypeManager:getFillTypesByFruitTypeCategoryName(specs.fruitTypeCategoryNames, nil) |
2776 | end |
2777 | end |
2778 | end |
2779 | return nil |
2780 | end |
getSpecValueStartFillUnitMassByMassData
DescriptionDefinitiongetSpecValueStartFillUnitMassByMassData()Code
2813 | function FillUnit.getSpecValueStartFillUnitMassByMassData(fillUnitMassData) |
2814 | local mass = 0 |
2815 | for _, massData in pairs(fillUnitMassData) do |
2816 | local fillType |
2817 | if massData.fillTypeCategories ~= nil then |
2818 | local fillTypes = g_fillTypeManager:getFillTypesByCategoryNames(massData.fillTypeCategories) |
2819 | fillType = fillTypes[1] |
2820 | elseif massData.fillTypes ~= nil then |
2821 | local fillTypes = g_fillTypeManager:getFillTypesByNames(massData.fillTypes) |
2822 | fillType = fillTypes[1] |
2823 | elseif massData.fillType ~= nil then |
2824 | fillType = g_fillTypeManager:getFillTypeIndexByName(massData.fillType) |
2825 | end |
2826 | |
2827 | if fillType ~= nil then |
2828 | local fillTypeDesc = g_fillTypeManager:getFillTypeByIndex(fillType) |
2829 | mass = mass + massData.capacity * fillTypeDesc.massPerLiter |
2830 | end |
2831 | end |
2832 | |
2833 | return mass |
2834 | end |
initSpecialization
DescriptionDefinitioninitSpecialization()Code
32 | function FillUnit.initSpecialization() |
33 | Vehicle.registerStateChange("FILLTYPE_CHANGE") |
34 | |
35 | g_configurationManager:addConfigurationType("fillUnit", g_i18n:getText("configuration_fillUnit"), "fillUnit", nil, nil, nil, ConfigurationUtil.SELECTOR_MULTIOPTION) |
36 | |
37 | g_storeManager:addSpecType("capacity", "shopListAttributeIconCapacity", FillUnit.loadSpecValueCapacity, FillUnit.getSpecValueCapacity, "vehicle", {"fillUnit"}) |
38 | g_storeManager:addSpecType("fillTypes", "shopListAttributeIconFillTypes", FillUnit.loadSpecValueFillTypes, FillUnit.getSpecValueFillTypes, "vehicle", {"fillUnit"}) |
39 | |
40 | local schema = Vehicle.xmlSchema |
41 | schema:setXMLSpecializationType("FillUnit") |
42 | |
43 | schema:register(XMLValueType.STRING, "vehicle.storeData.specs.fillTypes", "Fill types") |
44 | schema:register(XMLValueType.STRING, "vehicle.storeData.specs.fillTypeCategories", "Fill type categories") |
45 | schema:register(XMLValueType.FLOAT, "vehicle.storeData.specs.capacity", "Capacity") |
46 | FillUnit.registerUnitDisplaySchema(schema, "vehicle.storeData.specs.capacity") |
47 | |
48 | schema:register(XMLValueType.BOOL, FillUnit.FILL_UNIT_CONFIG_XML_KEY .. ".fillUnits#removeVehicleIfEmpty", "Remove vehicle if unit empty", false) |
49 | schema:register(XMLValueType.TIME, FillUnit.FILL_UNIT_CONFIG_XML_KEY .. ".fillUnits#removeVehicleDelay", "Delay for vehicle removal (e.g. can be used while sounds are still playing)", 0) |
50 | schema:register(XMLValueType.BOOL, FillUnit.FILL_UNIT_CONFIG_XML_KEY .. ".fillUnits#allowFoldingWhileFilled", "Allow folding while filled", true) |
51 | schema:register(XMLValueType.FLOAT, FillUnit.FILL_UNIT_CONFIG_XML_KEY .. ".fillUnits#allowFoldingThreshold", "Allow folding threshold", 0.0001) |
52 | schema:register(XMLValueType.FLOAT, FillUnit.FILL_UNIT_CONFIG_XML_KEY .. ".fillUnits#fillTypeChangeThreshold", "Fill type overwrite threshold", 0.05) |
53 | |
54 | schema:register(XMLValueType.FLOAT, FillUnit.FILL_UNIT_CONFIG_XML_KEY .. ".fillUnits.fillTrigger#litersPerSecond", "Fill liters per second", 200) |
55 | schema:register(XMLValueType.BOOL, FillUnit.FILL_UNIT_CONFIG_XML_KEY .. ".fillUnits.fillTrigger#consumePtoPower", "Consume pto power while filling", false) |
56 | |
57 | local fillUnitPath = FillUnit.FILL_UNIT_XML_KEY |
58 | |
59 | schema:register(XMLValueType.FLOAT, fillUnitPath .. "#capacity", "Capacity", "unlimited") |
60 | schema:register(XMLValueType.BOOL, fillUnitPath .. "#updateMass", "Update vehicle mass while fill level changes", true) |
61 | schema:register(XMLValueType.BOOL, fillUnitPath .. "#canBeUnloaded", "Can be unloaded", true) |
62 | |
63 | FillUnit.registerUnitDisplaySchema(schema, fillUnitPath) |
64 | schema:register(XMLValueType.BOOL, fillUnitPath .. "#showCapacityInShop", "Show capacity in shop", true) |
65 | schema:register(XMLValueType.BOOL, fillUnitPath .. "#showInShop", "Show in shop", true) |
66 | |
67 | schema:register(XMLValueType.NODE_INDEX, fillUnitPath .. ".exactFillRootNode#node", "Exact fill root node") |
68 | schema:register(XMLValueType.FLOAT, fillUnitPath .. ".exactFillRootNode#extraEffectDistance", "Exact fill root node extra distance", 0) |
69 | |
70 | schema:register(XMLValueType.NODE_INDEX, fillUnitPath .. ".autoAimTargetNode#node", "Auto aim target node") |
71 | schema:register(XMLValueType.FLOAT, fillUnitPath .. ".autoAimTargetNode#startZ", "Start Z translation") |
72 | schema:register(XMLValueType.FLOAT, fillUnitPath .. ".autoAimTargetNode#endZ", "End Z translation") |
73 | schema:register(XMLValueType.FLOAT, fillUnitPath .. ".autoAimTargetNode#startPercentage", "Start move percentage") |
74 | schema:register(XMLValueType.BOOL, fillUnitPath .. ".autoAimTargetNode#invert", "Invert Z movement") |
75 | |
76 | schema:register(XMLValueType.STRING, fillUnitPath .. "#fillTypeCategories", "Supported fill type categories") |
77 | schema:register(XMLValueType.STRING, fillUnitPath .. "#fillTypes", "Supported fill types") |
78 | |
79 | schema:register(XMLValueType.FLOAT, fillUnitPath .. "#startFillLevel", "Start fill level") |
80 | schema:register(XMLValueType.STRING, fillUnitPath .. "#startFillType", "Start fill type") |
81 | |
82 | schema:register(XMLValueType.NODE_INDEX, fillUnitPath .. ".fillRootNode#node", "Fill root node", "first component") |
83 | schema:register(XMLValueType.NODE_INDEX, fillUnitPath .. ".fillMassNode#node", "Fill root node", "first component") |
84 | schema:register(XMLValueType.BOOL, fillUnitPath .. "#updateFillLevelMass", "Update fill level mass", true) |
85 | schema:register(XMLValueType.BOOL, fillUnitPath .. "#ignoreFillLimit", "Ignores limiting of filling if the max mass is reached (if the settings is turned on)", false) |
86 | |
87 | schema:register(XMLValueType.BOOL, fillUnitPath .. "#synchronizeFillLevel", "Synchronize fill level", true) |
88 | schema:register(XMLValueType.BOOL, fillUnitPath .. "#synchronizeFullFillLevel", "Synchronize fill level as 32bit float instead of percentage with max. 16 bits", false) |
89 | schema:register(XMLValueType.INT, fillUnitPath .. "#synchronizationNumBits", "Synchronization bits") |
90 | |
91 | schema:register(XMLValueType.BOOL, fillUnitPath .. "#showOnHud", "Show on HUD", true) |
92 | schema:register(XMLValueType.BOOL, fillUnitPath .. "#showOnInfoHud", "Show on Info HUD", true) |
93 | schema:register(XMLValueType.INT, fillUnitPath .. "#uiPrecision", "Precision in UI display", 0) |
94 | schema:register(XMLValueType.BOOL, fillUnitPath .. "#blocksAutomatedTrainTravel", "Block automated train travel if not empty", false) |
95 | |
96 | schema:register(XMLValueType.STRING, fillUnitPath .. "#fillAnimation", "Fill animation name") |
97 | schema:register(XMLValueType.FLOAT, fillUnitPath .. "#fillAnimationLoadTime", "Fill animation load time") |
98 | schema:register(XMLValueType.FLOAT, fillUnitPath .. "#fillAnimationEmptyTime", "Fill animation empty time") |
99 | |
100 | schema:register(XMLValueType.STRING, fillUnitPath .. ".fillLevelAnimation#name", "Fill level animation name (Animation time is set depending on fill level percentage)") |
101 | schema:register(XMLValueType.BOOL, fillUnitPath .. ".fillLevelAnimation#resetOnEmpty", "Update animation when fill level reaches zero", true) |
102 | |
103 | schema:register(XMLValueType.FLOAT, fillUnitPath .. ".alarmTriggers.alarmTrigger(?)#minFillLevel", "Fill animation empty time") |
104 | schema:register(XMLValueType.FLOAT, fillUnitPath .. ".alarmTriggers.alarmTrigger(?)#maxFillLevel", "Fill animation empty time") |
105 | schema:register(XMLValueType.BOOL, fillUnitPath .. ".alarmTriggers.alarmTrigger(?)#needsTurnOn", "Needs turn on", false) |
106 | schema:register(XMLValueType.BOOL, fillUnitPath .. ".alarmTriggers.alarmTrigger(?)#turnOffInTrigger", "Turn off in trigger", false) |
107 | SoundManager.registerSampleXMLPaths(schema, fillUnitPath .. ".alarmTriggers.alarmTrigger(?)", "alarmSound") |
108 | |
109 | schema:register(XMLValueType.NODE_INDEX, fillUnitPath .. ".measurementNodes.measurementNode(?)#node", "Measurement node") |
110 | |
111 | schema:register(XMLValueType.NODE_INDEX, fillUnitPath .. ".fillPlane.node(?)#node", "Fill plane node") |
112 | schema:register(XMLValueType.FLOAT, fillUnitPath .. ".fillPlane.node(?).key(?)#time", "Key time") |
113 | schema:register(XMLValueType.VECTOR_TRANS, fillUnitPath .. ".fillPlane.node(?).key(?)#translation", "Translation") |
114 | schema:register(XMLValueType.FLOAT, fillUnitPath .. ".fillPlane.node(?).key(?)#y", "Y Translation") |
115 | schema:register(XMLValueType.VECTOR_ROT, fillUnitPath .. ".fillPlane.node(?).key(?)#rotation", "Rotation") |
116 | schema:register(XMLValueType.VECTOR_SCALE, fillUnitPath .. ".fillPlane.node(?).key(?)#scale", "Scale") |
117 | schema:register(XMLValueType.VECTOR_2, fillUnitPath .. ".fillPlane.node(?)#minMaxY", "Min. and max. Y translation") |
118 | schema:register(XMLValueType.BOOL, fillUnitPath .. ".fillPlane.node(?)#alwaysVisible", "Is always visible", false) |
119 | schema:register(XMLValueType.STRING, fillUnitPath .. ".fillPlane#defaultFillType", "Default fill type name") |
120 | |
121 | schema:register(XMLValueType.STRING, fillUnitPath .. ".fillTypeMaterials.material(?)#fillType", "Fill type name") |
122 | schema:register(XMLValueType.NODE_INDEX, fillUnitPath .. ".fillTypeMaterials.material(?)#node", "Node which receives material") |
123 | schema:register(XMLValueType.NODE_INDEX, fillUnitPath .. ".fillTypeMaterials.material(?)#refNode", "Node which provides material") |
124 | |
125 | EffectManager.registerEffectXMLPaths(schema, fillUnitPath .. ".fillEffect") |
126 | AnimationManager.registerAnimationNodesXMLPaths(schema, fillUnitPath .. ".animationNodes") |
127 | |
128 | Dashboard.registerDashboardXMLPaths(schema, fillUnitPath, "fillLevel | fillLevelPct | fillLevelWarning") |
129 | Dashboard.registerDashboardWarningXMLPaths(schema, fillUnitPath) |
130 | |
131 | schema:register(XMLValueType.NODE_INDEX, FillUnit.FILL_UNIT_CONFIG_XML_KEY .. ".fillUnits.unloading(?)#node", "Unloading node") |
132 | schema:register(XMLValueType.FLOAT, FillUnit.FILL_UNIT_CONFIG_XML_KEY .. ".fillUnits.unloading(?)#width", "Unloading width", 15) |
133 | schema:register(XMLValueType.VECTOR_TRANS, FillUnit.FILL_UNIT_CONFIG_XML_KEY .. ".fillUnits.unloading(?)#offset", "Unloading offset", "0 0 0") |
134 | |
135 | EffectManager.registerEffectXMLPaths(schema, FillUnit.FILL_UNIT_CONFIG_XML_KEY .. ".fillUnits.fillEffect") |
136 | AnimationManager.registerAnimationNodesXMLPaths(schema, FillUnit.FILL_UNIT_CONFIG_XML_KEY .. ".fillUnits.animationNodes") |
137 | SoundManager.registerSampleXMLPaths(schema, "vehicle.fillUnit.sounds", "fill") |
138 | |
139 | ObjectChangeUtil.registerObjectChangeXMLPaths(schema, FillUnit.FILL_UNIT_CONFIG_XML_KEY) |
140 | |
141 | schema:register(XMLValueType.INT, Leveler.LEVELER_NODE_XML_KEY .. "#fillUnitIndex", "Reference fill unit index", 1) |
142 | schema:register(XMLValueType.FLOAT, Leveler.LEVELER_NODE_XML_KEY .. "#minFillLevel", "Min. fill level to activate leveler node (pct between 0 and 1)", 0) |
143 | schema:register(XMLValueType.FLOAT, Leveler.LEVELER_NODE_XML_KEY .. "#maxFillLevel", "Max. fill level to activate leveler node (pct between 0 and 1)", 1) |
144 | |
145 | schema:setXMLSpecializationType() |
146 | |
147 | local schemaSavegame = Vehicle.xmlSchemaSavegame |
148 | schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).fillUnit.unit(?)#index", "Fill Unit index") |
149 | schemaSavegame:register(XMLValueType.STRING, "vehicles.vehicle(?).fillUnit.unit(?)#fillType", "Fill type") |
150 | schemaSavegame:register(XMLValueType.FLOAT, "vehicles.vehicle(?).fillUnit.unit(?)#fillLevel", "Fill level") |
151 | end |
loadAlarmTrigger
DescriptionDefinitionloadAlarmTrigger()Code
1749 | function FillUnit:loadAlarmTrigger(xmlFile, key, alarmTrigger, fillUnit) |
1750 | alarmTrigger.fillUnit = fillUnit |
1751 | alarmTrigger.isActive = false |
1752 | |
1753 | local success = true |
1754 | alarmTrigger.minFillLevel = xmlFile:getValue(key .. "#minFillLevel") |
1755 | if alarmTrigger.minFillLevel == nil then |
1756 | Logging.xmlWarning(self.xmlFile, "Missing 'minFillLevel' for alarmTrigger '%s'", key) |
1757 | success = false |
1758 | end |
1759 | |
1760 | alarmTrigger.maxFillLevel = xmlFile:getValue(key .. "#maxFillLevel") |
1761 | if alarmTrigger.maxFillLevel == nil then |
1762 | Logging.xmlWarning(self.xmlFile, "Missing 'maxFillLevel' for alarmTrigger '%s'", key) |
1763 | success = false |
1764 | end |
1765 | |
1766 | alarmTrigger.sample = g_soundManager:loadSampleFromXML(xmlFile, key, "alarmSound", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
1767 | |
1768 | return success |
1769 | end |
loadFillPlane
DescriptionDefinitionloadFillPlane()Code
1815 | function FillUnit:loadFillPlane(xmlFile, key, fillPlane, fillUnit) |
1816 | XMLUtil.checkDeprecatedXMLElements(xmlFile, key.."#fillType", "Material is dynamically assigned to the nodes") |
1817 | |
1818 | if not xmlFile:hasProperty(key) then |
1819 | return false |
1820 | end |
1821 | |
1822 | fillPlane.nodes = {} |
1823 | local i = 0 |
1824 | while true do |
1825 | local nodeKey = string.format("%s.node(%d)", key, i) |
1826 | if not xmlFile:hasProperty(nodeKey) then |
1827 | break |
1828 | end |
1829 | |
1830 | XMLUtil.checkDeprecatedXMLElements(xmlFile, nodeKey.."#index", nodeKey.."#node") -- FS17 to FS19 |
1831 | |
1832 | local node = xmlFile:getValue(nodeKey.."#node", nil, self.components, self.i3dMappings) |
1833 | if node ~= nil then |
1834 | local defaultX, defaultY, defaultZ = getTranslation(node) |
1835 | local defaultRX, defaultRY, defaultRZ = getRotation(node) |
1836 | |
1837 | local animCurve = AnimCurve.new(linearInterpolatorTransRotScale) |
1838 | local j = 0 |
1839 | while true do |
1840 | local animKey = string.format("%s.key(%d)", nodeKey, j) |
1841 | if not xmlFile:hasProperty(animKey) then |
1842 | break |
1843 | end |
1844 | |
1845 | local keyTime = xmlFile:getValue(animKey.."#time") |
1846 | if keyTime == nil then |
1847 | break |
1848 | end |
1849 | |
1850 | local x, y, z = xmlFile:getValue(animKey.."#translation") |
1851 | if y == nil then |
1852 | y = xmlFile:getValue(animKey.."#y") |
1853 | end |
1854 | x = x or defaultX |
1855 | y = y or defaultY |
1856 | z = z or defaultZ |
1857 | |
1858 | local rx, ry, rz = xmlFile:getValue(animKey.."#rotation") |
1859 | rx = rx or defaultRX |
1860 | ry = ry or defaultRY |
1861 | rz = rz or defaultRZ |
1862 | |
1863 | local sx, sy, sz = xmlFile:getValue(animKey.."#scale") |
1864 | sx = sx or 1 |
1865 | sy = sy or 1 |
1866 | sz = sz or 1 |
1867 | |
1868 | animCurve:addKeyframe({x=x, y=y, z=z, rx=rx, ry=ry, rz=rz, sx=sx, sy=sy, sz=sz, time = keyTime}) |
1869 | j = j + 1 |
1870 | end |
1871 | |
1872 | if j == 0 then |
1873 | local minY, maxY = xmlFile:getValue(nodeKey.."#minMaxY") |
1874 | minY = minY or defaultY |
1875 | maxY = maxY or defaultY |
1876 | animCurve:addKeyframe({defaultX, minY, defaultZ, defaultRX, defaultRY, defaultRZ, 1, 1, 1, time = 0}) |
1877 | animCurve:addKeyframe({defaultX, maxY, defaultZ, defaultRX, defaultRY, defaultRZ, 1, 1, 1, time = 1}) |
1878 | end |
1879 | |
1880 | local alwaysVisible = xmlFile:getValue(nodeKey.."#alwaysVisible", false) |
1881 | setVisibility(node, alwaysVisible) |
1882 | |
1883 | table.insert(fillPlane.nodes, {node=node, animCurve=animCurve, alwaysVisible=alwaysVisible}) |
1884 | end |
1885 | i = i + 1 |
1886 | end |
1887 | |
1888 | fillPlane.forcedFillType = nil |
1889 | |
1890 | local defaultFillTypeStr = xmlFile:getValue(key .. "#defaultFillType") |
1891 | if defaultFillTypeStr ~= nil then |
1892 | local defaultFillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(defaultFillTypeStr) |
1893 | if defaultFillTypeIndex == nil then |
1894 | Logging.xmlWarning(self.xmlFile, "Invalid defaultFillType '%s' for '%s'!", tostring(defaultFillTypeStr), key) |
1895 | return false |
1896 | else |
1897 | fillPlane.defaultFillType = defaultFillTypeIndex |
1898 | end |
1899 | else |
1900 | fillPlane.defaultFillType = next(fillUnit.supportedFillTypes) |
1901 | end |
1902 | |
1903 | return true |
1904 | end |
loadFillTypeMaterials
DescriptionDefinitionloadFillTypeMaterials()Code
1961 | function FillUnit:loadFillTypeMaterials(xmlFile, key) |
1962 | local fillTypeMaterials = {} |
1963 | xmlFile:iterate(key .. ".fillTypeMaterials.material", function(_, materialKey) |
1964 | local fillTypeName = xmlFile:getValue(materialKey .. "#fillType") |
1965 | if fillTypeName ~= nil then |
1966 | local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(fillTypeName) |
1967 | if fillTypeIndex ~= nil then |
1968 | local node = xmlFile:getValue(materialKey .. "#node", nil, self.components, self.i3dMappings) |
1969 | local refNode = xmlFile:getValue(materialKey .. "#refNode", nil, self.components, self.i3dMappings) |
1970 | if node ~= nil and refNode ~= nil then |
1971 | local fillTypeMaterial = {} |
1972 | fillTypeMaterial.fillTypeIndex = fillTypeIndex |
1973 | fillTypeMaterial.node = node |
1974 | fillTypeMaterial.refNode = refNode |
1975 | table.insert(fillTypeMaterials, fillTypeMaterial) |
1976 | else |
1977 | Logging.xmlWarning(xmlFile, "Missing node or ref node in '%s'", materialKey) |
1978 | end |
1979 | else |
1980 | Logging.xmlWarning(xmlFile, "Unknown fill type '%s' in '%s'", fillTypeName, materialKey) |
1981 | end |
1982 | else |
1983 | Logging.xmlWarning(xmlFile, "Missing fill type in '%s'", materialKey) |
1984 | end |
1985 | end) |
1986 | |
1987 | return fillTypeMaterials |
1988 | end |
loadFillUnitFromXML
DescriptionDefinitionloadFillUnitFromXML()Code
1536 | function FillUnit:loadFillUnitFromXML(xmlFile, key, entry, index) |
1537 | local spec = self.spec_fillUnit |
1538 | |
1539 | entry.fillUnitIndex = index |
1540 | entry.capacity = xmlFile:getValue(key .. "#capacity", math.huge) |
1541 | entry.defaultCapacity = entry.capacity |
1542 | entry.updateMass = xmlFile:getValue(key .. "#updateMass", true) |
1543 | entry.canBeUnloaded = xmlFile:getValue(key .. "#canBeUnloaded", true) |
1544 | entry.needsSaving = true |
1545 | |
1546 | entry.fillLevel = 0 |
1547 | entry.fillLevelSent = 0 |
1548 | |
1549 | entry.fillType = FillType.UNKNOWN |
1550 | entry.fillTypeSent = FillType.UNKNOWN |
1551 | entry.fillTypeToDisplay = FillType.UNKNOWN |
1552 | entry.fillLevelToDisplay = nil |
1553 | |
1554 | entry.lastValidFillType = FillType.UNKNOWN |
1555 | entry.lastValidFillTypeSent = FillType.UNKNOWN |
1556 | |
1557 | if xmlFile:hasProperty(key .. ".exactFillRootNode") then |
1558 | XMLUtil.checkDeprecatedXMLElements(xmlFile, key .. ".exactFillRootNode#index", key .. ".exactFillRootNode#node") --FS17 to FS19 |
1559 | |
1560 | entry.exactFillRootNode = xmlFile:getValue(key .. ".exactFillRootNode#node", nil, self.components, self.i3dMappings) |
1561 | if entry.exactFillRootNode ~= nil then |
1562 | if not CollisionFlag.getHasFlagSet(entry.exactFillRootNode, CollisionFlag.FILLABLE) then |
1563 | Logging.xmlWarning(self.xmlFile, "Missing collision mask bit '%d'. Please add this bit to exact fill root node '%s' in '%s'", CollisionFlag.getBit(CollisionFlag.FILLABLE), getName(entry.exactFillRootNode), key) |
1564 | return false |
1565 | end |
1566 | |
1567 | spec.exactFillRootNodeToFillUnit[entry.exactFillRootNode] = entry |
1568 | spec.exactFillRootNodeToExtraDistance[entry.exactFillRootNode] = xmlFile:getValue(key .. ".exactFillRootNode#extraEffectDistance", 0) |
1569 | spec.hasExactFillRootNodes = true |
1570 | else |
1571 | Logging.xmlWarning(self.xmlFile, "ExactFillRootNode not found for fillUnit '%s'!", key) |
1572 | end |
1573 | end |
1574 | |
1575 | XMLUtil.checkDeprecatedXMLElements(xmlFile, key .. ".autoAimTargetNode#index", key .. ".autoAimTargetNode#node") --FS17 to FS19 |
1576 | |
1577 | entry.autoAimTarget = {} |
1578 | entry.autoAimTarget.node = xmlFile:getValue(key .. ".autoAimTargetNode#node", nil, self.components, self.i3dMappings) |
1579 | if entry.autoAimTarget.node ~= nil then |
1580 | entry.autoAimTarget.baseTrans = {getTranslation(entry.autoAimTarget.node)} |
1581 | entry.autoAimTarget.startZ = xmlFile:getValue( key ..".autoAimTargetNode#startZ") |
1582 | entry.autoAimTarget.endZ = xmlFile:getValue( key ..".autoAimTargetNode#endZ") |
1583 | entry.autoAimTarget.startPercentage = xmlFile:getValue( key ..".autoAimTargetNode#startPercentage", 25) / 100 |
1584 | entry.autoAimTarget.invert = xmlFile:getValue( key ..".autoAimTargetNode#invert", false) |
1585 | if entry.autoAimTarget.startZ ~= nil and entry.autoAimTarget.endZ ~= nil then |
1586 | local startZ = entry.autoAimTarget.startZ |
1587 | if entry.autoAimTarget.invert then |
1588 | startZ = entry.autoAimTarget.endZ |
1589 | end |
1590 | |
1591 | setTranslation(entry.autoAimTarget.node, entry.autoAimTarget.baseTrans[1], entry.autoAimTarget.baseTrans[2], startZ) |
1592 | end |
1593 | end |
1594 | |
1595 | entry.supportedFillTypes = {} |
1596 | local fillTypes |
1597 | local fillTypeCategories = xmlFile:getValue(key .. "#fillTypeCategories") |
1598 | local fillTypeNames = xmlFile:getValue(key .. "#fillTypes") |
1599 | if fillTypeCategories ~= nil and fillTypeNames == nil then |
1600 | fillTypes = g_fillTypeManager:getFillTypesByCategoryNames(fillTypeCategories, "Warning: '"..self.configFileName.. "' has invalid fillTypeCategory '%s'.") |
1601 | elseif fillTypeCategories == nil and fillTypeNames ~= nil then |
1602 | fillTypes = g_fillTypeManager:getFillTypesByNames(fillTypeNames, "Warning: '"..self.configFileName.. "' has invalid fillType '%s'.") |
1603 | else |
1604 | Logging.xmlWarning(self.xmlFile, "Missing 'fillTypeCategories' or 'fillTypes' for fillUnit '%s'", key) |
1605 | return false |
1606 | end |
1607 | |
1608 | if fillTypes ~= nil then |
1609 | for _,fillType in pairs(fillTypes) do |
1610 | entry.supportedFillTypes[fillType] = true |
1611 | end |
1612 | end |
1613 | |
1614 | entry.supportedToolTypes = {} |
1615 | for i=1, g_toolTypeManager:getNumberOfToolTypes() do |
1616 | entry.supportedToolTypes[i] = true |
1617 | end |
1618 | |
1619 | local startFillLevel = xmlFile:getValue(key .. "#startFillLevel") |
1620 | local startFillTypeStr = xmlFile:getValue(key .. "#startFillType") |
1621 | if startFillTypeStr ~= nil then |
1622 | local startFillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(startFillTypeStr) |
1623 | if startFillTypeIndex ~= nil then |
1624 | entry.startFillLevel = startFillLevel |
1625 | entry.startFillTypeIndex = startFillTypeIndex |
1626 | end |
1627 | end |
1628 | |
1629 | entry.fillRootNode = xmlFile:getValue(key .. ".fillRootNode#node", nil, self.components, self.i3dMappings) |
1630 | if entry.fillRootNode == nil then |
1631 | entry.fillRootNode = self.components[1].node |
1632 | end |
1633 | |
1634 | entry.fillMassNode = xmlFile:getValue(key .. ".fillMassNode#node", nil, self.components, self.i3dMappings) |
1635 | local updateFillLevelMass = xmlFile:getValue(key .. "#updateFillLevelMass", true) |
1636 | if entry.fillMassNode == nil and updateFillLevelMass then |
1637 | entry.fillMassNode = self.components[1].node |
1638 | end |
1639 | |
1640 | entry.ignoreFillLimit = xmlFile:getValue(key .. "#ignoreFillLimit", false) |
1641 | |
1642 | -- mp sync info |
1643 | entry.synchronizeFillLevel = xmlFile:getValue(key .. "#synchronizeFillLevel", true) |
1644 | entry.synchronizeFullFillLevel = xmlFile:getValue(key .. "#synchronizeFullFillLevel", false) |
1645 | |
1646 | local defaultBits = 16 |
1647 | for startCapacity, bits in pairs(FillUnit.CAPACITY_TO_NETWORK_BITS) do |
1648 | if entry.capacity >= startCapacity then |
1649 | defaultBits = bits |
1650 | end |
1651 | end |
1652 | |
1653 | entry.synchronizationNumBits = xmlFile:getValue(key .. "#synchronizationNumBits", defaultBits) |
1654 | |
1655 | entry.showOnHud = xmlFile:getValue(key .. "#showOnHud", true) |
1656 | entry.showOnInfoHud = xmlFile:getValue(key .. "#showOnInfoHud", true) |
1657 | entry.uiPrecision = xmlFile:getValue(key .. "#uiPrecision", 0) |
1658 | local unitText = xmlFile:getValue(key .. "#unitTextOverride") |
1659 | if unitText ~= nil then |
1660 | entry.unitText = g_i18n:convertText(unitText) |
1661 | end |
1662 | entry.parentUnitOnHud = nil |
1663 | entry.childUnitOnHud = nil |
1664 | entry.blocksAutomatedTrainTravel = xmlFile:getValue(key .. "#blocksAutomatedTrainTravel", false) |
1665 | |
1666 | entry.fillAnimation = xmlFile:getValue(key .. "#fillAnimation") |
1667 | entry.fillAnimationLoadTime = xmlFile:getValue(key .. "#fillAnimationLoadTime") |
1668 | entry.fillAnimationEmptyTime = xmlFile:getValue(key .. "#fillAnimationEmptyTime") |
1669 | |
1670 | entry.fillLevelAnimationName = xmlFile:getValue(key .. ".fillLevelAnimation#name") |
1671 | entry.fillLevelAnimationResetOnEmpty = xmlFile:getValue(key .. ".fillLevelAnimation#resetOnEmpty", true) |
1672 | |
1673 | |
1674 | -- |
1675 | if self.isClient then |
1676 | entry.alarmTriggers = {} |
1677 | local i = 0 |
1678 | while true do |
1679 | local nodeKey = key .. string.format(".alarmTriggers.alarmTrigger(%d)", i) |
1680 | if not xmlFile:hasProperty(nodeKey) then |
1681 | break |
1682 | end |
1683 | local alarmTrigger = {} |
1684 | if self:loadAlarmTrigger(xmlFile, nodeKey, alarmTrigger, entry) then |
1685 | table.insert(entry.alarmTriggers, alarmTrigger) |
1686 | end |
1687 | i = i + 1 |
1688 | end |
1689 | |
1690 | entry.measurementNodes = {} |
1691 | i = 0 |
1692 | while true do |
1693 | local nodeKey = key .. string.format(".measurementNodes.measurementNode(%d)", i) |
1694 | if not xmlFile:hasProperty(nodeKey) then |
1695 | break |
1696 | end |
1697 | |
1698 | local measurementNode = {} |
1699 | if self:loadMeasurementNode(xmlFile, nodeKey, measurementNode) then |
1700 | table.insert(entry.measurementNodes, measurementNode) |
1701 | end |
1702 | |
1703 | i = i + 1 |
1704 | end |
1705 | |
1706 | entry.fillPlane = {} |
1707 | entry.lastFillPlaneType = nil |
1708 | if not self:loadFillPlane(xmlFile, key..".fillPlane", entry.fillPlane, entry) then |
1709 | entry.fillPlane = nil |
1710 | end |
1711 | |
1712 | entry.fillTypeMaterials = self:loadFillTypeMaterials(xmlFile, key) |
1713 | |
1714 | entry.fillEffects = g_effectManager:loadEffect(xmlFile, key .. ".fillEffect", self.components, self, self.i3dMappings) |
1715 | entry.animationNodes = g_animationManager:loadAnimations(xmlFile, key..".animationNodes", self.components, self, self.i3dMappings) |
1716 | |
1717 | XMLUtil.checkDeprecatedXMLElements(xmlFile, key .. ".fillLevelHud", key .. ".dashboard") --FS17 to FS19 |
1718 | |
1719 | if self.loadDashboardsFromXML ~= nil then |
1720 | self:loadDashboardsFromXML(xmlFile, key, {valueTypeToLoad = "fillLevel", |
1721 | valueObject = entry, |
1722 | valueFunc = "fillLevel", |
1723 | minFunc = 0, |
1724 | maxFunc = "capacity"}) |
1725 | |
1726 | self:loadDashboardsFromXML(xmlFile, key, {valueTypeToLoad = "fillLevelPct", |
1727 | valueObject = entry, |
1728 | valueFunc = function(fillUnit) |
1729 | return MathUtil.clamp(fillUnit.fillLevel/fillUnit.capacity, 0, 1) * 100 |
1730 | end, |
1731 | minFunc = 0, |
1732 | maxFunc = 100}) |
1733 | |
1734 | self:loadDashboardsFromXML(xmlFile, key, {valueTypeToLoad = "fillLevelWarning", |
1735 | valueObject = entry, |
1736 | valueFunc = "fillLevel", |
1737 | minFunc = 0, |
1738 | maxFunc = "capacity", |
1739 | additionalAttributesFunc = Dashboard.warningAttributes, |
1740 | stateFunc = Dashboard.warningState}) |
1741 | end |
1742 | end |
1743 | |
1744 | return true |
1745 | end |
loadFillUnitUnloadingFromXML
DescriptionDefinitionloadFillUnitUnloadingFromXML()Code
1155 | function FillUnit:loadFillUnitUnloadingFromXML(xmlFile, key, entry, index) |
1156 | entry.node = xmlFile:getValue(key.."#node", self.rootNode, self.components, self.i3dMappings) |
1157 | entry.width = xmlFile:getValue(key.."#width", 15) |
1158 | entry.offset = xmlFile:getValue(key.."#offset", "0 0 0", true) |
1159 | |
1160 | return true |
1161 | end |
loadLevelerNodeFromXML
DescriptionDefinitionloadLevelerNodeFromXML()Code
2395 | function FillUnit:loadLevelerNodeFromXML(superFunc, levelerNode, xmlFile, key) |
2396 | levelerNode.limitFillUnitIndex = xmlFile:getValue(key.."#fillUnitIndex", 1) |
2397 | levelerNode.minFillLevel = xmlFile:getValue(key.."#minFillLevel", 0) |
2398 | levelerNode.maxFillLevel = xmlFile:getValue(key.."#maxFillLevel", 1) |
2399 | |
2400 | return superFunc(self, levelerNode, xmlFile, key) |
2401 | end |
loadMeasurementNode
DescriptionDefinitionloadMeasurementNode()Code
1773 | function FillUnit:loadMeasurementNode(xmlFile, key, entry) |
1774 | XMLUtil.checkDeprecatedXMLElements(xmlFile, key.."#index", key.."#node") |
1775 | |
1776 | local node = xmlFile:getValue(key .. "#node", nil, self.components, self.i3dMappings) |
1777 | if node == nil then |
1778 | Logging.xmlWarning(self.xmlFile, "Missing 'node' for measurementNode '%s'", key) |
1779 | return false |
1780 | end |
1781 | entry.node = node |
1782 | entry.measurementTime = 0 |
1783 | entry.intensity = 0 |
1784 | |
1785 | return true |
1786 | end |
loadMovingToolFromXML
DescriptionDefinitionloadMovingToolFromXML()Code
2294 | function FillUnit:loadMovingToolFromXML(superFunc, xmlFile, key, entry) |
2295 | if not superFunc(self, xmlFile, key, entry) then |
2296 | return false |
2297 | end |
2298 | |
2299 | entry.fillUnitIndex = xmlFile:getValue(key .. "#fillUnitIndex") |
2300 | entry.minFillLevel = xmlFile:getValue(key .. "#minFillLevel") |
2301 | entry.maxFillLevel = xmlFile:getValue(key .. "#maxFillLevel") |
2302 | |
2303 | return true |
2304 | end |
loadSpecValueCapacity
DescriptionDefinitionloadSpecValueCapacity()Code
2455 | function FillUnit.loadSpecValueCapacity(xmlFile, customEnvironment, baseDir) |
2456 | -- check if #unitText or #unit was set and convert capacity, liters otherwise |
2457 | local function getUnitCapacityAndText(fillUnitKey, capacity) |
2458 | local unitText = xmlFile:getValue(fillUnitKey .. "#unitTextOverride") |
2459 | if unitText == nil then |
2460 | local unitId = xmlFile:getValue(fillUnitKey .. "#shopDisplayUnit") |
2461 | local convFuncAndL10n = FillUnit.UNIT[unitId] |
2462 | if unitId ~= nil and convFuncAndL10n == nil then |
2463 | Logging.xmlWarning(xmlFile, "Unit '%s' is not defined in fillUnit '%s'. Available units: %s. Using LITER as default", unitId, fillUnitKey, table.concatKeys(FillUnit.UNIT, " ")) |
2464 | end |
2465 | convFuncAndL10n = convFuncAndL10n or FillUnit.UNIT["LITER"] |
2466 | return convFuncAndL10n.conversionFunc(capacity), convFuncAndL10n.l10n, convFuncAndL10n.conversionFunc |
2467 | end |
2468 | return capacity, unitText |
2469 | end |
2470 | |
2471 | local rootName = xmlFile:getRootName() |
2472 | local fillUnitConfigurations = {} |
2473 | |
2474 | XMLUtil.checkDeprecatedXMLElements(xmlFile, rootName..".storeData.specs.capacity#unit", rootName..".storeData.specs.capacity#unitTextOverride") --FS19 to FS22 |
2475 | |
2476 | local overwrittenCapacity = xmlFile:getValue(rootName..".storeData.specs.capacity") |
2477 | local overwrittenUnitText |
2478 | local conversionFunc |
2479 | |
2480 | if overwrittenCapacity ~= nil then |
2481 | overwrittenCapacity, overwrittenUnitText, conversionFunc = getUnitCapacityAndText(rootName..".storeData.specs.capacity", overwrittenCapacity) |
2482 | end |
2483 | |
2484 | if overwrittenCapacity ~= nil and overwrittenUnitText ~= nil then |
2485 | table.insert(fillUnitConfigurations, {{capacity=overwrittenCapacity, unit=overwrittenUnitText, conversionFunc=conversionFunc}}) |
2486 | return fillUnitConfigurations |
2487 | end |
2488 | |
2489 | xmlFile:iterate(rootName..".fillUnit.fillUnitConfigurations.fillUnitConfiguration",function(_, key) |
2490 | local fillUnitConfiguration = {} |
2491 | |
2492 | xmlFile:iterate(key..".fillUnits.fillUnit", function(fillUnitIndex, fillUnitKey) |
2493 | |
2494 | XMLUtil.checkDeprecatedXMLElements(xmlFile, fillUnitKey.."#unit", fillUnitKey.."#unitTextOverride") --FS19 to FS22 |
2495 | |
2496 | if xmlFile:getValue(fillUnitKey.."#showCapacityInShop") ~= false and xmlFile:getValue(fillUnitKey.."#showInShop") ~= false then |
2497 | local capacity = xmlFile:getValue(fillUnitKey .. "#capacity") or 0 |
2498 | local unitText |
2499 | |
2500 | capacity, unitText, conversionFunc = getUnitCapacityAndText(fillUnitKey, capacity) |
2501 | |
2502 | table.insert(fillUnitConfiguration, {capacity=capacity, unit=unitText, conversionFunc=conversionFunc, fillUnitIndex=fillUnitIndex}) |
2503 | end |
2504 | end) |
2505 | |
2506 | table.insert(fillUnitConfigurations, fillUnitConfiguration) |
2507 | end) |
2508 | |
2509 | if #fillUnitConfigurations > 0 then |
2510 | return fillUnitConfigurations |
2511 | end |
2512 | end |
loadSpecValueFillTypes
DescriptionDefinitionloadSpecValueFillTypes()Code
2620 | function FillUnit.loadSpecValueFillTypes(xmlFile, customEnvironment, baseDir) |
2621 | local fillTypeNames = nil |
2622 | local fillTypeCategoryNames = nil |
2623 | local fillTypes = nil |
2624 | local fruitTypeNames = nil |
2625 | local fillTypesByConfiguration = {} |
2626 | |
2627 | local rootName = xmlFile:getRootName() |
2628 | |
2629 | XMLUtil.checkDeprecatedXMLElements(xmlFile, rootName..".fillTypes", rootName..".cutter#fruitTypes") --FS19 to FS21 |
2630 | XMLUtil.checkDeprecatedXMLElements(xmlFile, rootName..".fruitTypes", rootName..".storeData.specs.fillTypes") --FS19 to FS21 |
2631 | XMLUtil.checkDeprecatedXMLElements(xmlFile, rootName..".fillTypeCategories", rootName..".storeData.specs.fillTypeCategories") --FS19 to FS21 |
2632 | |
2633 | -- get fill types of all configurations and all fill units to display all possible fill types |
2634 | local i = 0 |
2635 | while true do |
2636 | local key = string.format(rootName..".fillUnit.fillUnitConfigurations.fillUnitConfiguration(%d)", i) |
2637 | if not xmlFile:hasProperty(key) then |
2638 | break |
2639 | end |
2640 | |
2641 | local j = 0 |
2642 | while true do |
2643 | local unitKey = string.format(key..".fillUnits.fillUnit(%d)", j) |
2644 | if not xmlFile:hasProperty(unitKey) then |
2645 | break |
2646 | end |
2647 | |
2648 | local showInShop = xmlFile:getValue(unitKey.."#showInShop") |
2649 | local capacity = xmlFile:getValue(unitKey.."#capacity") |
2650 | if (showInShop == nil or showInShop) and (capacity == nil or capacity > 0) then |
2651 | local currentFillTypes = xmlFile:getValue(unitKey .. "#fillTypes") |
2652 | if currentFillTypes ~= nil then |
2653 | if fillTypeNames == nil then |
2654 | fillTypeNames = currentFillTypes |
2655 | else |
2656 | fillTypeNames = fillTypeNames .. " " .. currentFillTypes |
2657 | end |
2658 | end |
2659 | |
2660 | local currentFillTypeCategories = xmlFile:getValue(unitKey .. "#fillTypeCategories") |
2661 | if currentFillTypeCategories ~= nil then |
2662 | if fillTypeCategoryNames == nil then |
2663 | fillTypeCategoryNames = currentFillTypeCategories |
2664 | else |
2665 | fillTypeCategoryNames = fillTypeCategoryNames .. " " .. currentFillTypeCategories |
2666 | end |
2667 | end |
2668 | |
2669 | fillTypesByConfiguration[i + 1] = {fillTypeNames=currentFillTypes, categoryNames=currentFillTypeCategories} |
2670 | end |
2671 | |
2672 | j = j + 1 |
2673 | end |
2674 | |
2675 | i = i + 1 |
2676 | end |
2677 | |
2678 | local overwrittenFillTypeNames = xmlFile:getValue(rootName..".storeData.specs.fillTypes") |
2679 | if overwrittenFillTypeNames ~= nil then |
2680 | fillTypeNames = overwrittenFillTypeNames |
2681 | fillTypeCategoryNames = nil |
2682 | end |
2683 | |
2684 | if fillTypes == nil then |
2685 | fruitTypeNames = xmlFile:getValue(rootName..".cutter#fruitTypes") |
2686 | end |
2687 | |
2688 | local fruitTypeCategoryNames = xmlFile:getValue(rootName..".cutter#fruitTypeCategories") |
2689 | local useWindrowed = xmlFile:getValue(rootName..".cutter#useWindrowed", false) |
2690 | |
2691 | fillTypeCategoryNames = xmlFile:getValue(rootName..".storeData.specs.fillTypeCategories", fillTypeCategoryNames) |
2692 | |
2693 | return {categoryNames=fillTypeCategoryNames, fillTypeNames=fillTypeNames, fruitTypeNames=fruitTypeNames, fruitTypeCategoryNames=fruitTypeCategoryNames, useWindrowed=useWindrowed, fillTypesByConfiguration=fillTypesByConfiguration} |
2694 | end |
loadSpecValueFillUnitMassData
DescriptionDefinitionloadSpecValueFillUnitMassData()Code
2784 | function FillUnit.loadSpecValueFillUnitMassData(xmlFile, customEnvironment, baseDir) |
2785 | local fillUnitMassData = {} |
2786 | xmlFile:iterate("vehicle.motorized.consumerConfigurations.consumerConfiguration(0).consumer", function(index, key) |
2787 | local fillUnitIndex = xmlFile:getValue(key .. "#fillUnitIndex", 0) |
2788 | if fillUnitIndex ~= 0 then |
2789 | local unitKey = string.format("vehicle.fillUnit.fillUnitConfigurations.fillUnitConfiguration(0).fillUnits.fillUnit(%d)", fillUnitIndex - 1) |
2790 | |
2791 | local fillTypeCategories = xmlFile:getValue(unitKey .. "#fillTypeCategories") |
2792 | local fillTypes = xmlFile:getValue(unitKey .. "#fillTypes") |
2793 | local capacity = xmlFile:getValue(unitKey .. "#capacity", 0) |
2794 | if capacity > 0 then |
2795 | table.insert(fillUnitMassData, {fillTypeCategories=fillTypeCategories, fillTypes=fillTypes, capacity=capacity}) |
2796 | end |
2797 | end |
2798 | end) |
2799 | |
2800 | xmlFile:iterate("vehicle.fillUnit.fillUnitConfigurations.fillUnitConfiguration(0).fillUnits.fillUnit", function(index, key) |
2801 | local startFillLevel = xmlFile:getValue(key .. "#startFillLevel", 0) |
2802 | if startFillLevel > 0 then |
2803 | local startFillType = xmlFile:getValue(key .. "#startFillType") |
2804 | table.insert(fillUnitMassData, {fillType=startFillType, capacity=startFillLevel}) |
2805 | end |
2806 | end) |
2807 | |
2808 | return fillUnitMassData |
2809 | end |
onDeactivate
DescriptionDefinitiononDeactivate()Code
712 | function FillUnit:onDeactivate() |
713 | local spec = self.spec_fillUnit |
714 | if spec.fillTrigger.isFilling then |
715 | self:setFillUnitIsFilling(false, true) |
716 | end |
717 | |
718 | for _, fillUnit in pairs(spec.fillUnits) do |
719 | self:updateMeasurementNodes(fillUnit, 0, false, 0) |
720 | end |
721 | end |
onDelete
DescriptionDefinitiononDelete()Code
443 | function FillUnit:onDelete() |
444 | local spec = self.spec_fillUnit |
445 | |
446 | if spec.fillTrigger ~= nil then |
447 | g_currentMission.activatableObjectsSystem:removeActivatable(spec.fillTrigger.activatable) |
448 | for _, trigger in pairs(spec.fillTrigger.triggers) do |
449 | trigger:onVehicleDeleted(self) |
450 | end |
451 | end |
452 | |
453 | if spec.fillUnits ~= nil then |
454 | for _, fillUnit in ipairs(spec.fillUnits) do |
455 | for _, alarmTrigger in ipairs(fillUnit.alarmTriggers) do |
456 | g_soundManager:deleteSample(alarmTrigger.sample) |
457 | end |
458 | end |
459 | end |
460 | |
461 | g_soundManager:deleteSamples(spec.samples) |
462 | |
463 | if spec.unloadTrigger ~= nil then |
464 | spec.unloadTrigger:delete() |
465 | end |
466 | if spec.loadTrigger ~= nil then |
467 | spec.loadTrigger:delete() |
468 | end |
469 | end |
onDischargeTargetObjectChanged
DescriptionDefinitiononDischargeTargetObjectChanged()Code
754 | function FillUnit:onDischargeTargetObjectChanged(dischargeObject) |
755 | -- update unloading action event in case we overlap with the overloading action |
756 | FillUnit.updateUnloadActionDisplay(self) |
757 | end |
onDraw
DescriptionDefinitiononDraw()Code
703 | function FillUnit:onDraw(isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
704 | if self:getDrawFirstFillText() then |
705 | local spec = self.spec_fillUnit |
706 | g_currentMission:addExtraPrintText(spec.texts.firstFillTheTool) |
707 | end |
708 | end |
onLoad
DescriptionDefinitiononLoad()Code
280 | function FillUnit:onLoad(savegame) |
281 | local spec = self.spec_fillUnit |
282 | |
283 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.measurementNodes.measurementNode", "vehicle.fillUnit.fillUnitConfigurations.fillUnitConfiguration.fillUnits.fillUnit.measurementNodes.measurementNode") |
284 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.fillPlanes.fillPlane", "vehicle.fillUnit.fillUnitConfigurations.fillUnitConfiguration.fillUnits.fillUnit.fillPlane") |
285 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.foldable.foldingParts#onlyFoldOnEmpty", "vehicle.fillUnit#allowFoldingWhileFilled") |
286 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.fillAutoAimTargetNode", "vehicle.fillUnit.fillUnitConfigurations.fillUnitConfiguration.fillUnits.fillUnit.autoAimTargetNode") --FS17 to FS19 |
287 | |
288 | local fillUnitConfigurationId = Utils.getNoNil(self.configurations["fillUnit"], 1) |
289 | local baseKey = string.format("vehicle.fillUnit.fillUnitConfigurations.fillUnitConfiguration(%d).fillUnits", fillUnitConfigurationId -1) |
290 | ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.fillUnit.fillUnitConfigurations.fillUnitConfiguration", fillUnitConfigurationId , self.components, self) |
291 | |
292 | spec.removeVehicleIfEmpty = self.xmlFile:getValue(baseKey.."#removeVehicleIfEmpty", false) |
293 | spec.removeVehicleDelay = self.xmlFile:getValue(baseKey.."#removeVehicleDelay", 0) |
294 | spec.allowFoldingWhileFilled = self.xmlFile:getValue(baseKey.."#allowFoldingWhileFilled", true) |
295 | spec.allowFoldingThreshold = self.xmlFile:getValue(baseKey.."#allowFoldingThreshold", 0.0001) |
296 | spec.fillTypeChangeThreshold = self.xmlFile:getValue(baseKey.."#fillTypeChangeThreshold", 0.05) -- fill level percentage that still allows overriding with another fill type |
297 | spec.fillUnits = {} |
298 | spec.exactFillRootNodeToFillUnit = {} |
299 | spec.exactFillRootNodeToExtraDistance = {} |
300 | spec.hasExactFillRootNodes = false |
301 | spec.activeAlarmTriggers = {} |
302 | |
303 | spec.fillTrigger = {} |
304 | spec.fillTrigger.triggers = {} |
305 | spec.fillTrigger.activatable = FillActivatable.new(self) |
306 | spec.fillTrigger.isFilling = false |
307 | spec.fillTrigger.currentTrigger = nil -- trigger that is currently used for filling |
308 | spec.fillTrigger.selectedTrigger = nil -- currently used trigger no matter if filling or not |
309 | spec.fillTrigger.litersPerSecond = self.xmlFile:getValue(baseKey..".fillTrigger#litersPerSecond", 200) |
310 | spec.fillTrigger.consumePtoPower = self.xmlFile:getValue(baseKey..".fillTrigger#consumePtoPower", false) |
311 | |
312 | local i=0 |
313 | while true do |
314 | local key = string.format("%s.fillUnit(%d)", baseKey, i) |
315 | if not self.xmlFile:hasProperty(key) then |
316 | break |
317 | end |
318 | local entry = {} |
319 | |
320 | if self:loadFillUnitFromXML(self.xmlFile, key, entry, i+1) then |
321 | table.insert(spec.fillUnits, entry) |
322 | else |
323 | Logging.xmlWarning(self.xmlFile, "Could not load fillUnit for '%s'", key) |
324 | self:setLoadingState(VehicleLoadingUtil.VEHICLE_LOAD_ERROR) |
325 | break |
326 | end |
327 | |
328 | i = i + 1 |
329 | end |
330 | |
331 | if self.xmlFile:hasProperty(baseKey..".unloading") then |
332 | spec.unloading = {} |
333 | self.xmlFile:iterate(baseKey ..".unloading", function(_, unloadingKey) |
334 | local entry = {} |
335 | |
336 | if self:loadFillUnitUnloadingFromXML(self.xmlFile, unloadingKey, entry, i+1) then |
337 | table.insert(spec.unloading, entry) |
338 | else |
339 | Logging.xmlWarning(self.xmlFile, "Could not load unloading node for '%s'", unloadingKey) |
340 | return false |
341 | end |
342 | end) |
343 | end |
344 | |
345 | if self.isClient then |
346 | spec.samples = {} |
347 | spec.samples.fill = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.fillUnit.sounds", "fill", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
348 | |
349 | spec.fillEffects = g_effectManager:loadEffect(self.xmlFile, baseKey .. ".fillEffect", self.components, self, self.i3dMappings) |
350 | spec.animationNodes = g_animationManager:loadAnimations(self.xmlFile, baseKey..".animationNodes", self.components, self, self.i3dMappings) |
351 | |
352 | spec.activeFillEffects = {} |
353 | spec.activeFillAnimations = {} |
354 | end |
355 | |
356 | spec.texts = {} |
357 | spec.texts.warningFoldingFilled = g_i18n:getText("warning_foldingNotWhileFilled") |
358 | spec.texts.firstFillTheTool = g_i18n:getText("info_firstFillTheTool") |
359 | spec.texts.unloadNoSpace = g_i18n:getText("fillUnit_unload_nospace") |
360 | spec.texts.stopRefill = g_i18n:getText("action_stopRefillingOBJECT") |
361 | spec.texts.startRefill = g_i18n:getText("action_refillOBJECT") |
362 | |
363 | spec.isInfoDirty = false |
364 | spec.fillUnitInfos = {} |
365 | |
366 | spec.dirtyFlag = self:getNextDirtyFlag() |
367 | end |
onPostLoad
DescriptionDefinitiononPostLoad()Code
371 | function FillUnit:onPostLoad(savegame) |
372 | local spec = self.spec_fillUnit |
373 | |
374 | if self.isServer then |
375 | -- fill units that do not have a start fill level will be only loaded from savegame if not reseted and savegame available |
376 | local fillUnitsToLoad = {} |
377 | for i, fillUnit in ipairs(spec.fillUnits) do |
378 | if fillUnit.startFillLevel == nil and fillUnit.startFillTypeIndex == nil then |
379 | fillUnitsToLoad[i] = fillUnit |
380 | end |
381 | end |
382 | |
383 | -- if the fill units are not in the savegame we fill them also with the start fill level (e.g. on a new savegame) |
384 | if savegame ~= nil and savegame.xmlFile:hasProperty(savegame.key..".fillUnit") then |
385 | local i = 0 |
386 | local xmlFile = savegame.xmlFile |
387 | while true do |
388 | local key = string.format("%s.fillUnit.unit(%d)", savegame.key, i) |
389 | if not xmlFile:hasProperty(key) then |
390 | break |
391 | end |
392 | |
393 | local fillUnitIndex = xmlFile:getValue(key.."#index") |
394 | |
395 | local allowLoading = fillUnitsToLoad[fillUnitIndex] == nil or -- always load (fill unit with start fill level) |
396 | (fillUnitsToLoad[fillUnitIndex] ~= nil and not savegame.resetVehicles) -- only load if not reseted (fill unit without start fill level) |
397 | if allowLoading then |
398 | local fillTypeName = xmlFile:getValue(key.."#fillType") |
399 | local fillLevel = xmlFile:getValue(key.."#fillLevel") |
400 | local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(fillTypeName) |
401 | self:addFillUnitFillLevel(self:getOwnerFarmId(), fillUnitIndex, fillLevel, fillTypeIndex, ToolType.UNDEFINED, nil) |
402 | |
403 | local fillUnit = spec.fillUnits[fillUnitIndex] |
404 | if fillUnit ~= nil and fillUnit.fillLevelAnimationName ~= nil then |
405 | AnimatedVehicle.updateAnimationByName(self, fillUnit.fillLevelAnimationName, 9999999, true) |
406 | end |
407 | end |
408 | |
409 | i = i + 1 |
410 | end |
411 | else |
412 | -- fill units that are filled by a start fill level are always loaded from the savegame (otherwise you could cheat if you reset the vehicle) |
413 | for fillUnitIndex, fillUnit in pairs(spec.fillUnits) do |
414 | if fillUnit.startFillLevel ~= nil and fillUnit.startFillTypeIndex ~= nil then |
415 | self:addFillUnitFillLevel(self:getOwnerFarmId(), fillUnitIndex, fillUnit.startFillLevel, fillUnit.startFillTypeIndex, ToolType.UNDEFINED, nil) |
416 | |
417 | if fillUnit.fillLevelAnimationName ~= nil then |
418 | AnimatedVehicle.updateAnimationByName(self, fillUnit.fillLevelAnimationName, 9999999, true) |
419 | end |
420 | end |
421 | end |
422 | end |
423 | |
424 | for i, fillUnit in ipairs(spec.fillUnits) do |
425 | self:updateAlarmTriggers(fillUnit.alarmTriggers) |
426 | end |
427 | end |
428 | |
429 | if #spec.fillUnits == 0 then |
430 | SpecializationUtil.removeEventListener(self, "onReadStream", FillUnit) |
431 | SpecializationUtil.removeEventListener(self, "onWriteStream", FillUnit) |
432 | SpecializationUtil.removeEventListener(self, "onReadUpdateStream", FillUnit) |
433 | SpecializationUtil.removeEventListener(self, "onWriteUpdateStream", FillUnit) |
434 | SpecializationUtil.removeEventListener(self, "onUpdateTick", FillUnit) |
435 | SpecializationUtil.removeEventListener(self, "onDraw", FillUnit) |
436 | SpecializationUtil.removeEventListener(self, "onDeactivate", FillUnit) |
437 | SpecializationUtil.removeEventListener(self, "onRegisterActionEvents", FillUnit) |
438 | end |
439 | end |
onReadStream
DescriptionDefinitiononReadStream()Code
512 | function FillUnit:onReadStream(streamId, connection) |
513 | if connection:getIsServer() then |
514 | local spec = self.spec_fillUnit |
515 | |
516 | self:setFillUnitIsFilling(streamReadBool(streamId), true) |
517 | |
518 | if spec.loadTrigger ~= nil then |
519 | local loadTriggerId = streamReadInt32(streamId) |
520 | spec.loadTrigger:readStream(streamId, connection) |
521 | g_client:finishRegisterObject(self.loadTrigger, loadTriggerId) |
522 | end |
523 | if spec.unloadTrigger ~= nil then |
524 | local unloadTriggerId = streamReadInt32(streamId) |
525 | spec.unloadTrigger:readStream(streamId, connection) |
526 | g_client:finishRegisterObject(self.unloadTrigger, unloadTriggerId) |
527 | end |
528 | for i=1,table.getn(spec.fillUnits) do |
529 | if spec.fillUnits[i].synchronizeFillLevel then |
530 | local fillLevel = streamReadFloat32(streamId) |
531 | local fillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS) |
532 | |
533 | self:addFillUnitFillLevel(self:getOwnerFarmId(), i, fillLevel, fillType, ToolType.UNDEFINED, nil) |
534 | |
535 | local lastValidFillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS) |
536 | self:setFillUnitLastValidFillType(i, lastValidFillType, true) |
537 | end |
538 | end |
539 | end |
540 | end |
onReadUpdateStream
DescriptionDefinitiononReadUpdateStream()Code
573 | function FillUnit:onReadUpdateStream(streamId, timestamp, connection) |
574 | if connection:getIsServer() then |
575 | local spec = self.spec_fillUnit |
576 | |
577 | if streamReadBool(streamId) then |
578 | for i=1,table.getn(spec.fillUnits) do |
579 | local fillUnit = spec.fillUnits[i] |
580 | if fillUnit.synchronizeFillLevel then |
581 | local fillLevel |
582 | if fillUnit.synchronizeFullFillLevel then |
583 | fillLevel = streamReadFloat32(streamId) |
584 | else |
585 | local maxValue = 2^fillUnit.synchronizationNumBits - 1 |
586 | fillLevel = fillUnit.capacity * streamReadUIntN(streamId, fillUnit.synchronizationNumBits) / maxValue |
587 | end |
588 | |
589 | local fillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS) |
590 | if fillLevel ~= fillUnit.fillLevel or fillType ~= fillUnit.fillType then |
591 | local oldFillType = self:getFillUnitFillType(i) |
592 | |
593 | -- if fill type is unknown we empty the fillUnit |
594 | if fillType == FillType.UNKNOWN then |
595 | self:addFillUnitFillLevel(self:getOwnerFarmId(), i, -math.huge, oldFillType, ToolType.UNDEFINED, nil) |
596 | else |
597 | -- in case the fill type was switched dynamically |
598 | if oldFillType ~= FillType.UNKNOWN and fillType ~= oldFillType then |
599 | self:setFillUnitFillType(i, fillType) |
600 | end |
601 | |
602 | self:addFillUnitFillLevel(self:getOwnerFarmId(), i, fillLevel-fillUnit.fillLevel, fillType, ToolType.UNDEFINED, nil) |
603 | end |
604 | end |
605 | |
606 | local lastValidFillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS) |
607 | self:setFillUnitLastValidFillType(i, lastValidFillType, lastValidFillType ~= fillUnit.lastValidFillType) |
608 | end |
609 | end |
610 | end |
611 | end |
612 | end |
onRegisterActionEvents
DescriptionDefinitiononRegisterActionEvents()Code
725 | function FillUnit:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection) |
726 | if self.isClient then |
727 | local spec = self.spec_fillUnit |
728 | self:clearActionEventsTable(spec.actionEvents) |
729 | if isActiveForInputIgnoreSelection then |
730 | if self.isServer and GS_IS_CONSOLE_VERSION and g_isDevelopmentVersion then |
731 | local _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.CONSOLE_DEBUG_FILLUNIT_NEXT, self, FillUnit.actionEventConsoleFillUnitNext, false, true, false, true, nil) |
732 | g_inputBinding:setActionEventTextVisibility(actionEventId, false) |
733 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_VERY_LOW) |
734 | _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.CONSOLE_DEBUG_FILLUNIT_INC, self, FillUnit.actionEventConsoleFillUnitInc, false, true, false, true, nil) |
735 | g_inputBinding:setActionEventTextVisibility(actionEventId, false) |
736 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_VERY_LOW) |
737 | _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.CONSOLE_DEBUG_FILLUNIT_DEC, self, FillUnit.actionEventConsoleFillUnitDec, false, true, false, true, nil) |
738 | g_inputBinding:setActionEventTextVisibility(actionEventId, false) |
739 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_VERY_LOW) |
740 | end |
741 | |
742 | if spec.unloading ~= nil then |
743 | local _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.UNLOAD, self, FillUnit.actionEventUnload, false, true, false, true, nil) |
744 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL) |
745 | spec.unloadActionEventId = actionEventId |
746 | FillUnit.updateUnloadActionDisplay(self) |
747 | end |
748 | end |
749 | end |
750 | end |
onUpdateTick
DescriptionDefinitiononUpdateTick()Code
645 | function FillUnit:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
646 | local spec = self.spec_fillUnit |
647 | |
648 | if self.isServer and spec.fillTrigger.isFilling then |
649 | local delta = 0 |
650 | local trigger = spec.fillTrigger.currentTrigger |
651 | if trigger ~= nil then |
652 | delta = spec.fillTrigger.litersPerSecond*dt*0.001 |
653 | delta = trigger:fillVehicle(self, delta, dt) |
654 | end |
655 | |
656 | if delta <= 0 then |
657 | self:setFillUnitIsFilling(false) |
658 | end |
659 | end |
660 | |
661 | if self.isClient then |
662 | for _, fillUnit in pairs(spec.fillUnits) do |
663 | self:updateMeasurementNodes(fillUnit, dt, false) |
664 | end |
665 | |
666 | self:updateAlarmTriggers(spec.activeAlarmTriggers) |
667 | |
668 | |
669 | local needsUpdate = false |
670 | |
671 | -- stop effects |
672 | for effect, time in pairs(spec.activeFillEffects) do |
673 | time = time - dt |
674 | if time < 0 then |
675 | g_effectManager:stopEffects(effect) |
676 | spec.activeFillEffects[effect] = nil |
677 | else |
678 | needsUpdate = true |
679 | spec.activeFillEffects[effect] = time |
680 | end |
681 | end |
682 | |
683 | -- stop animations |
684 | for animationNodes, time in pairs(spec.activeFillAnimations) do |
685 | time = time - dt |
686 | if time < 0 then |
687 | g_animationManager:stopAnimations(animationNodes) |
688 | spec.activeFillAnimations[animationNodes] = nil |
689 | else |
690 | needsUpdate = true |
691 | spec.activeFillAnimations[animationNodes] = time |
692 | end |
693 | end |
694 | |
695 | if needsUpdate then |
696 | self:raiseActive() |
697 | end |
698 | end |
699 | end |
onWriteStream
DescriptionDefinitiononWriteStream()Code
544 | function FillUnit:onWriteStream(streamId, connection) |
545 | if not connection:getIsServer() then |
546 | local spec = self.spec_fillUnit |
547 | |
548 | streamWriteBool(streamId, spec.fillTrigger.isFilling) |
549 | |
550 | if spec.loadTrigger ~= nil then |
551 | streamWriteInt32(streamId, NetworkUtil.getObjectId(spec.loadTrigger)) |
552 | spec.loadTrigger:writeStream(streamId, connection) |
553 | g_server:registerObjectInStream(connection, spec.loadTrigger) |
554 | end |
555 | if spec.unloadTrigger ~= nil then |
556 | streamWriteInt32(streamId, NetworkUtil.getObjectId(spec.unloadTrigger)) |
557 | spec.unloadTrigger:writeStream(streamId, connection) |
558 | g_server:registerObjectInStream(connection, spec.unloadTrigger) |
559 | end |
560 | for i=1,table.getn(spec.fillUnits) do |
561 | if spec.fillUnits[i].synchronizeFillLevel then |
562 | local fillUnit = spec.fillUnits[i] |
563 | streamWriteFloat32(streamId, fillUnit.fillLevel) |
564 | streamWriteUIntN(streamId, fillUnit.fillType, FillTypeManager.SEND_NUM_BITS) |
565 | streamWriteUIntN(streamId, fillUnit.lastValidFillType, FillTypeManager.SEND_NUM_BITS) |
566 | end |
567 | end |
568 | end |
569 | end |
onWriteUpdateStream
DescriptionDefinitiononWriteUpdateStream()Code
616 | function FillUnit:onWriteUpdateStream(streamId, connection, dirtyMask) |
617 | if not connection:getIsServer() then |
618 | local spec = self.spec_fillUnit |
619 | |
620 | if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlag) ~= 0) then |
621 | for i=1,table.getn(spec.fillUnits) do |
622 | local fillUnit = spec.fillUnits[i] |
623 | if fillUnit.synchronizeFillLevel then |
624 | if fillUnit.synchronizeFullFillLevel then |
625 | streamWriteFloat32(streamId, fillUnit.fillLevelSent) |
626 | else |
627 | local percent = 0 |
628 | if fillUnit.capacity > 0 then |
629 | percent = MathUtil.clamp(fillUnit.fillLevelSent / fillUnit.capacity, 0, 1) |
630 | end |
631 | |
632 | local value = math.floor(percent * (2^fillUnit.synchronizationNumBits - 1) + 0.5) |
633 | streamWriteUIntN(streamId, value, fillUnit.synchronizationNumBits) |
634 | end |
635 | streamWriteUIntN(streamId, fillUnit.fillTypeSent, FillTypeManager.SEND_NUM_BITS) |
636 | streamWriteUIntN(streamId, fillUnit.lastValidFillTypeSent, FillTypeManager.SEND_NUM_BITS) |
637 | end |
638 | end |
639 | end |
640 | end |
641 | end |
prerequisitesPresent
DescriptionDefinitionprerequisitesPresent()Code
162 | function FillUnit.prerequisitesPresent(specializations) |
163 | return true |
164 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
263 | function FillUnit.registerEventListeners(vehicleType) |
264 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", FillUnit) |
265 | SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", FillUnit) |
266 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", FillUnit) |
267 | SpecializationUtil.registerEventListener(vehicleType, "onReadStream", FillUnit) |
268 | SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", FillUnit) |
269 | SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", FillUnit) |
270 | SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", FillUnit) |
271 | SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", FillUnit) |
272 | SpecializationUtil.registerEventListener(vehicleType, "onDraw", FillUnit) |
273 | SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", FillUnit) |
274 | SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", FillUnit) |
275 | SpecializationUtil.registerEventListener(vehicleType, "onDischargeTargetObjectChanged", FillUnit) |
276 | end |
registerEvents
DescriptionDefinitionregisterEvents()Code
168 | function FillUnit.registerEvents(vehicleType) |
169 | SpecializationUtil.registerEvent(vehicleType, "onFillUnitFillLevelChanged") |
170 | SpecializationUtil.registerEvent(vehicleType, "onChangedFillType") |
171 | SpecializationUtil.registerEvent(vehicleType, "onAlarmTriggerChanged") |
172 | SpecializationUtil.registerEvent(vehicleType, "onAddedFillUnitTrigger") |
173 | SpecializationUtil.registerEvent(vehicleType, "onFillUnitTriggerChanged") |
174 | SpecializationUtil.registerEvent(vehicleType, "onRemovedFillUnitTrigger") |
175 | SpecializationUtil.registerEvent(vehicleType, "onFillUnitIsFillingStateChanged") |
176 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
180 | function FillUnit.registerFunctions(vehicleType) |
181 | SpecializationUtil.registerFunction(vehicleType, "getDrawFirstFillText", FillUnit.getDrawFirstFillText) |
182 | SpecializationUtil.registerFunction(vehicleType, "getFillUnits", FillUnit.getFillUnits) |
183 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitByIndex", FillUnit.getFillUnitByIndex) |
184 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitExists", FillUnit.getFillUnitExists) |
185 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitCapacity", FillUnit.getFillUnitCapacity) |
186 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitFreeCapacity", FillUnit.getFillUnitFreeCapacity) |
187 | SpecializationUtil.registerFunction(vehicleType, "getIsFillAllowedFromFarm", FillUnit.getIsFillAllowedFromFarm) |
188 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitFillLevel", FillUnit.getFillUnitFillLevel) |
189 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitFillLevelPercentage", FillUnit.getFillUnitFillLevelPercentage) |
190 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitFillType", FillUnit.getFillUnitFillType) |
191 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitLastValidFillType", FillUnit.getFillUnitLastValidFillType) |
192 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitFirstSupportedFillType", FillUnit.getFillUnitFirstSupportedFillType) |
193 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitExactFillRootNode", FillUnit.getFillUnitExactFillRootNode) |
194 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitRootNode", FillUnit.getFillUnitRootNode) |
195 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitAutoAimTargetNode", FillUnit.getFillUnitAutoAimTargetNode) |
196 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitSupportsFillType", FillUnit.getFillUnitSupportsFillType) |
197 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitSupportsToolType", FillUnit.getFillUnitSupportsToolType) |
198 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitSupportsToolTypeAndFillType", FillUnit.getFillUnitSupportsToolTypeAndFillType) |
199 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitSupportedFillTypes", FillUnit.getFillUnitSupportedFillTypes) |
200 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitSupportedToolTypes", FillUnit.getFillUnitSupportedToolTypes) |
201 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitAllowsFillType", FillUnit.getFillUnitAllowsFillType) |
202 | SpecializationUtil.registerFunction(vehicleType, "getFillTypeChangeThreshold", FillUnit.getFillTypeChangeThreshold) |
203 | SpecializationUtil.registerFunction(vehicleType, "getFirstValidFillUnitToFill", FillUnit.getFirstValidFillUnitToFill) |
204 | SpecializationUtil.registerFunction(vehicleType, "setFillUnitFillType", FillUnit.setFillUnitFillType) |
205 | SpecializationUtil.registerFunction(vehicleType, "setFillUnitFillTypeToDisplay", FillUnit.setFillUnitFillTypeToDisplay) |
206 | SpecializationUtil.registerFunction(vehicleType, "setFillUnitFillLevelToDisplay", FillUnit.setFillUnitFillLevelToDisplay) |
207 | SpecializationUtil.registerFunction(vehicleType, "setFillUnitCapacity", FillUnit.setFillUnitCapacity) |
208 | SpecializationUtil.registerFunction(vehicleType, "setFillUnitForcedMaterialFillType", FillUnit.setFillUnitForcedMaterialFillType) |
209 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitForcedMaterialFillType", FillUnit.getFillUnitForcedMaterialFillType) |
210 | SpecializationUtil.registerFunction(vehicleType, "updateAlarmTriggers", FillUnit.updateAlarmTriggers) |
211 | SpecializationUtil.registerFunction(vehicleType, "getAlarmTriggerIsActive", FillUnit.getAlarmTriggerIsActive) |
212 | SpecializationUtil.registerFunction(vehicleType, "setAlarmTriggerState", FillUnit.setAlarmTriggerState) |
213 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitIndexFromNode", FillUnit.getFillUnitIndexFromNode) |
214 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitExtraDistanceFromNode", FillUnit.getFillUnitExtraDistanceFromNode) |
215 | SpecializationUtil.registerFunction(vehicleType, "getFillUnitFromNode", FillUnit.getFillUnitFromNode) |
216 | SpecializationUtil.registerFunction(vehicleType, "addFillUnitFillLevel", FillUnit.addFillUnitFillLevel) |
217 | SpecializationUtil.registerFunction(vehicleType, "setFillUnitLastValidFillType", FillUnit.setFillUnitLastValidFillType) |
218 | SpecializationUtil.registerFunction(vehicleType, "loadFillUnitFromXML", FillUnit.loadFillUnitFromXML) |
219 | SpecializationUtil.registerFunction(vehicleType, "loadAlarmTrigger", FillUnit.loadAlarmTrigger) |
220 | SpecializationUtil.registerFunction(vehicleType, "loadMeasurementNode", FillUnit.loadMeasurementNode) |
221 | SpecializationUtil.registerFunction(vehicleType, "updateMeasurementNodes", FillUnit.updateMeasurementNodes) |
222 | SpecializationUtil.registerFunction(vehicleType, "loadFillPlane", FillUnit.loadFillPlane) |
223 | SpecializationUtil.registerFunction(vehicleType, "setFillPlaneForcedFillType", FillUnit.setFillPlaneForcedFillType) |
224 | SpecializationUtil.registerFunction(vehicleType, "updateFillUnitFillPlane", FillUnit.updateFillUnitFillPlane) |
225 | SpecializationUtil.registerFunction(vehicleType, "loadFillTypeMaterials", FillUnit.loadFillTypeMaterials) |
226 | SpecializationUtil.registerFunction(vehicleType, "updateFillTypeMaterials", FillUnit.updateFillTypeMaterials) |
227 | SpecializationUtil.registerFunction(vehicleType, "updateFillUnitAutoAimTarget", FillUnit.updateFillUnitAutoAimTarget) |
228 | SpecializationUtil.registerFunction(vehicleType, "addFillUnitTrigger", FillUnit.addFillUnitTrigger) |
229 | SpecializationUtil.registerFunction(vehicleType, "removeFillUnitTrigger", FillUnit.removeFillUnitTrigger) |
230 | SpecializationUtil.registerFunction(vehicleType, "setFillUnitIsFilling", FillUnit.setFillUnitIsFilling) |
231 | SpecializationUtil.registerFunction(vehicleType, "setFillSoundIsPlaying", FillUnit.setFillSoundIsPlaying) |
232 | SpecializationUtil.registerFunction(vehicleType, "getIsFillUnitActive", FillUnit.getIsFillUnitActive) |
233 | SpecializationUtil.registerFunction(vehicleType, "updateFillUnitTriggers", FillUnit.updateFillUnitTriggers) |
234 | SpecializationUtil.registerFunction(vehicleType, "emptyAllFillUnits", FillUnit.emptyAllFillUnits) |
235 | SpecializationUtil.registerFunction(vehicleType, "unloadFillUnits", FillUnit.unloadFillUnits) |
236 | SpecializationUtil.registerFunction(vehicleType, "loadFillUnitUnloadingFromXML", FillUnit.loadFillUnitUnloadingFromXML) |
237 | SpecializationUtil.registerFunction(vehicleType, "getAllowLoadTriggerActivation", FillUnit.getAllowLoadTriggerActivation) |
238 | SpecializationUtil.registerFunction(vehicleType, "debugGetSupportedFillTypesPerFillUnit", FillUnit.debugGetSupportedFillTypesPerFillUnit) |
239 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
244 | function FillUnit.registerOverwrittenFunctions(vehicleType) |
245 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAdditionalComponentMass", FillUnit.getAdditionalComponentMass) |
246 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "addNodeObjectMapping", FillUnit.addNodeObjectMapping) |
247 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "removeNodeObjectMapping", FillUnit.removeNodeObjectMapping) |
248 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getFillLevelInformation", FillUnit.getFillLevelInformation) |
249 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsFoldAllowed", FillUnit.getIsFoldAllowed) |
250 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsReadyForAutomatedTrainTravel", FillUnit.getIsReadyForAutomatedTrainTravel) |
251 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadMovingToolFromXML", FillUnit.loadMovingToolFromXML) |
252 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsMovingToolActive", FillUnit.getIsMovingToolActive) |
253 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDoConsumePtoPower", FillUnit.getDoConsumePtoPower) |
254 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsPowerTakeOffActive", FillUnit.getIsPowerTakeOffActive) |
255 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeTurnedOn", FillUnit.getCanBeTurnedOn) |
256 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "showInfo", FillUnit.showInfo) |
257 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadLevelerNodeFromXML", FillUnit.loadLevelerNodeFromXML) |
258 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsLevelerPickupNodeActive", FillUnit.getIsLevelerPickupNodeActive) |
259 | end |
registerUnitDisplaySchema
DescriptionDefinitionregisterUnitDisplaySchema()Code
155 | function FillUnit.registerUnitDisplaySchema(schema, key) |
156 | schema:register(XMLValueType.STRING, key .. "#shopDisplayUnit", "Unit used for displaying the capacity in shop (converts to given unit from capacity in liters)", "LITER") |
157 | schema:register(XMLValueType.STRING, key .. "#unitTextOverride", "Unit text override, no conversion performed on given capacity") |
158 | end |
removeFillUnitTrigger
DescriptionRemoves fill triggerDefinition
removeFillUnitTrigger(table trigger)Arguments
table | trigger | trigger |
2043 | function FillUnit:removeFillUnitTrigger(trigger) |
2044 | local spec = self.spec_fillUnit |
2045 | table.removeElement(spec.fillTrigger.triggers, trigger) |
2046 | |
2047 | if self.isServer and trigger == spec.fillTrigger.currentTrigger then |
2048 | self:setFillUnitIsFilling(false) |
2049 | end |
2050 | |
2051 | if #spec.fillTrigger.triggers == 0 then |
2052 | g_currentMission.activatableObjectsSystem:removeActivatable(spec.fillTrigger.activatable) |
2053 | |
2054 | -- automatic filling for mobile version |
2055 | if self.isServer and Platform.gameplay.automaticFilling then |
2056 | self:setFillUnitIsFilling(false) |
2057 | end |
2058 | end |
2059 | |
2060 | SpecializationUtil.raiseEvent(self, "onRemovedFillUnitTrigger", #spec.fillTrigger.triggers) |
2061 | |
2062 | self:updateFillUnitTriggers() |
2063 | end |
removeNodeObjectMapping
DescriptionDefinitionremoveNodeObjectMapping()Code
2199 | function FillUnit:removeNodeObjectMapping(superFunc, list) |
2200 | superFunc(self, list) |
2201 | |
2202 | local spec = self.spec_fillUnit |
2203 | |
2204 | if spec.fillUnits ~= nil then |
2205 | for _,fillUnit in pairs(spec.fillUnits) do |
2206 | if fillUnit.fillRootNode ~= nil then |
2207 | list[fillUnit.fillRootNode] = nil |
2208 | end |
2209 | if fillUnit.exactFillRootNode ~= nil then |
2210 | list[fillUnit.exactFillRootNode] = nil |
2211 | end |
2212 | end |
2213 | end |
2214 | end |
saveStatsToXMLFile
DescriptionDefinitionsaveStatsToXMLFile()Code
490 | function FillUnit:saveStatsToXMLFile(xmlFile, key) |
491 | local spec = self.spec_fillUnit |
492 | |
493 | local fillTypes = '' |
494 | local fillLevels = '' |
495 | local numFillUnits = table.getn(spec.fillUnits) |
496 | for i,fillUnit in ipairs(spec.fillUnits) do |
497 | local fillTypeName = Utils.getNoNil(g_fillTypeManager:getFillTypeNameByIndex(fillUnit.fillType), "unknown") |
498 | fillTypes = fillTypes .. HTMLUtil.encodeToHTML(tostring(fillTypeName)) |
499 | fillLevels = fillLevels .. string.format("%.3f", fillUnit.fillLevel) |
500 | if numFillUnits > 1 and i ~= numFillUnits then |
501 | fillTypes = fillTypes .. ' ' |
502 | fillLevels = fillLevels .. ' ' |
503 | end |
504 | end |
505 | |
506 | setXMLString(xmlFile, key.."#fillTypes", fillTypes) |
507 | setXMLString(xmlFile, key.."#fillLevels", fillLevels) |
508 | end |
saveToXMLFile
DescriptionDefinitionsaveToXMLFile()Code
473 | function FillUnit:saveToXMLFile(xmlFile, key, usedModNames) |
474 | local spec = self.spec_fillUnit |
475 | local i = 0 |
476 | for k, fillUnit in ipairs(spec.fillUnits) do |
477 | if fillUnit.needsSaving then |
478 | local fillUnitKey = string.format("%s.unit(%d)", key, i) |
479 | local fillTypeName = Utils.getNoNil(g_fillTypeManager:getFillTypeNameByIndex(fillUnit.fillType), "unknown") |
480 | xmlFile:setValue(fillUnitKey.."#index", k) |
481 | xmlFile:setValue(fillUnitKey.."#fillType", fillTypeName) |
482 | xmlFile:setValue(fillUnitKey.."#fillLevel", fillUnit.fillLevel) |
483 | i = i + 1 |
484 | end |
485 | end |
486 | end |
setAlarmTriggerState
DescriptionDefinitionsetAlarmTriggerState()Code
1089 | function FillUnit:setAlarmTriggerState(alarmTrigger, state) |
1090 | local spec = self.spec_fillUnit |
1091 | |
1092 | if state ~= alarmTrigger.isActive then |
1093 | if state then |
1094 | if alarmTrigger.sample ~= nil then |
1095 | g_soundManager:playSample(alarmTrigger.sample) |
1096 | end |
1097 | spec.activeAlarmTriggers[alarmTrigger] = alarmTrigger |
1098 | else |
1099 | if alarmTrigger.sample ~= nil then |
1100 | g_soundManager:stopSample(alarmTrigger.sample) |
1101 | end |
1102 | spec.activeAlarmTriggers[alarmTrigger] = nil |
1103 | end |
1104 | |
1105 | alarmTrigger.isActive = state |
1106 | SpecializationUtil.raiseEvent(self, "onAlarmTriggerChanged", alarmTrigger, state) |
1107 | end |
1108 | end |
setFillPlaneForcedFillType
DescriptionDefinitionsetFillPlaneForcedFillType()Code
1909 | function FillUnit:setFillPlaneForcedFillType(fillUnitIndex, forcedFillType) |
1910 | local spec = self.spec_fillUnit |
1911 | if spec.fillUnits[fillUnitIndex] ~= nil then |
1912 | if spec.fillUnits[fillUnitIndex].fillPlane ~= nil then |
1913 | spec.fillUnits[fillUnitIndex].fillPlane.forcedFillType = forcedFillType |
1914 | end |
1915 | end |
1916 | end |
setFillSoundIsPlaying
DescriptionDefinitionsetFillSoundIsPlaying()Code
2142 | function FillUnit:setFillSoundIsPlaying(isPlaying) |
2143 | local spec = self.spec_fillUnit |
2144 | if isPlaying then |
2145 | if not g_soundManager:getIsSamplePlaying(spec.samples.fill) then |
2146 | g_soundManager:playSample(spec.samples.fill) |
2147 | end |
2148 | else |
2149 | if g_soundManager:getIsSamplePlaying(spec.samples.fill) then |
2150 | g_soundManager:stopSample(spec.samples.fill) |
2151 | end |
2152 | end |
2153 | end |
setFillUnitCapacity
DescriptionDefinitionsetFillUnitCapacity()Code
1029 | function FillUnit:setFillUnitCapacity(fillUnitIndex, capacity, noEventSend) |
1030 | local spec = self.spec_fillUnit |
1031 | if spec.fillUnits[fillUnitIndex] ~= nil then |
1032 | if capacity ~= spec.fillUnits[fillUnitIndex].capacity then |
1033 | spec.fillUnits[fillUnitIndex].capacity = capacity |
1034 | |
1035 | SetFillUnitCapacityEvent.sendEvent(self, fillUnitIndex, capacity, noEventSend) |
1036 | end |
1037 | end |
1038 | end |
setFillUnitFillLevelToDisplay
DescriptionDefinitionsetFillUnitFillLevelToDisplay()Code
1019 | function FillUnit:setFillUnitFillLevelToDisplay(fillUnitIndex, fillLevel, isPersistent) |
1020 | local spec = self.spec_fillUnit |
1021 | if spec.fillUnits[fillUnitIndex] ~= nil then |
1022 | spec.fillUnits[fillUnitIndex].fillLevelToDisplay = fillLevel |
1023 | spec.fillUnits[fillUnitIndex].fillLevelToDisplayIsPersistent = isPersistent ~= nil and isPersistent |
1024 | end |
1025 | end |
setFillUnitFillType
DescriptionDefinitionsetFillUnitFillType()Code
998 | function FillUnit:setFillUnitFillType(fillUnitIndex, fillTypeIndex) |
999 | local spec = self.spec_fillUnit |
1000 | local oldFillTypeIndex = spec.fillUnits[fillUnitIndex].fillType |
1001 | if oldFillTypeIndex ~= fillTypeIndex then |
1002 | spec.fillUnits[fillUnitIndex].fillType = fillTypeIndex |
1003 | SpecializationUtil.raiseEvent(self, "onChangedFillType", fillUnitIndex, fillTypeIndex, oldFillTypeIndex) |
1004 | end |
1005 | end |
setFillUnitFillTypeToDisplay
DescriptionDefinitionsetFillUnitFillTypeToDisplay()Code
1009 | function FillUnit:setFillUnitFillTypeToDisplay(fillUnitIndex, fillTypeIndex, isPersistent) |
1010 | local spec = self.spec_fillUnit |
1011 | if spec.fillUnits[fillUnitIndex] ~= nil then |
1012 | spec.fillUnits[fillUnitIndex].fillTypeToDisplay = fillTypeIndex |
1013 | spec.fillUnits[fillUnitIndex].fillTypeToDisplayIsPersistent = isPersistent ~= nil and isPersistent |
1014 | end |
1015 | end |
setFillUnitForcedMaterialFillType
DescriptionDefinitionsetFillUnitForcedMaterialFillType()Code
1042 | function FillUnit:setFillUnitForcedMaterialFillType(fillUnitIndex, forcedMaterialFillType) |
1043 | local spec = self.spec_fillUnit |
1044 | if spec.fillUnits[fillUnitIndex] ~= nil then |
1045 | spec.fillUnits[fillUnitIndex].forcedMaterialFillType = forcedMaterialFillType |
1046 | end |
1047 | |
1048 | self:setFillPlaneForcedFillType(fillUnitIndex, forcedMaterialFillType) |
1049 | |
1050 | if self.setFillVolumeForcedFillTypeByFillUnitIndex ~= nil then |
1051 | self:setFillVolumeForcedFillTypeByFillUnitIndex(fillUnitIndex, forcedMaterialFillType) |
1052 | end |
1053 | end |
setFillUnitIsFilling
DescriptionDefinitionsetFillUnitIsFilling()Code
2102 | function FillUnit:setFillUnitIsFilling(isFilling, noEventSend) |
2103 | local spec = self.spec_fillUnit |
2104 | if isFilling ~= spec.fillTrigger.isFilling then |
2105 | if noEventSend == nil or noEventSend == false then |
2106 | if g_server ~= nil then |
2107 | g_server:broadcastEvent(SetFillUnitIsFillingEvent.new(self, isFilling), nil, nil, self) |
2108 | else |
2109 | g_client:getServerConnection():sendEvent(SetFillUnitIsFillingEvent.new(self, isFilling)) |
2110 | end |
2111 | end |
2112 | |
2113 | spec.fillTrigger.isFilling = isFilling |
2114 | if isFilling then |
2115 | -- find the first trigger which is activable |
2116 | spec.fillTrigger.currentTrigger = nil |
2117 | for _, trigger in ipairs(spec.fillTrigger.triggers) do |
2118 | if trigger:getIsActivatable(self) then |
2119 | spec.fillTrigger.currentTrigger = trigger |
2120 | break |
2121 | end |
2122 | end |
2123 | end |
2124 | if self.isClient then |
2125 | self:setFillSoundIsPlaying(isFilling) |
2126 | |
2127 | if spec.fillTrigger.currentTrigger ~= nil then |
2128 | spec.fillTrigger.currentTrigger:setFillSoundIsPlaying(isFilling) |
2129 | end |
2130 | end |
2131 | |
2132 | SpecializationUtil.raiseEvent(self, "onFillUnitIsFillingStateChanged", isFilling) |
2133 | |
2134 | if not isFilling then |
2135 | self:updateFillUnitTriggers() |
2136 | end |
2137 | end |
2138 | end |
setFillUnitLastValidFillType
DescriptionDefinitionsetFillUnitLastValidFillType()Code
1524 | function FillUnit:setFillUnitLastValidFillType(fillUnitIndex, fillType, force) |
1525 | local spec = self.spec_fillUnit |
1526 | local fillUnit = spec.fillUnits[fillUnitIndex] |
1527 | if fillUnit ~= nil and fillUnit.lastValidFillType ~= fillType then |
1528 | fillUnit.lastValidFillType = fillType |
1529 | fillUnit.lastValidFillTypeSent = fillType |
1530 | self:raiseDirtyFlags(spec.dirtyFlag) |
1531 | end |
1532 | end |
showInfo
DescriptionDefinitionshowInfo()Code
2349 | function FillUnit:showInfo(superFunc, box) |
2350 | local spec = self.spec_fillUnit |
2351 | |
2352 | if spec.isInfoDirty then |
2353 | spec.fillUnitInfos = {} |
2354 | local fillTypeToInfo = {} |
2355 | |
2356 | for _, fillUnit in ipairs(spec.fillUnits) do |
2357 | if fillUnit.showOnInfoHud and fillUnit.fillLevel > 0 then |
2358 | local info = fillTypeToInfo[fillUnit.fillType] |
2359 | if info == nil then |
2360 | local fillType = g_fillTypeManager:getFillTypeByIndex(fillUnit.fillType) |
2361 | info = {title=fillType.title, fillLevel=0, unit=fillUnit.unitText, precision=0} |
2362 | table.insert(spec.fillUnitInfos, info) |
2363 | fillTypeToInfo[fillUnit.fillType] = info |
2364 | end |
2365 | |
2366 | info.fillLevel = info.fillLevel + fillUnit.fillLevel |
2367 | if info.precision == 0 and fillUnit.fillLevel > 0 then |
2368 | info.precision = fillUnit.uiPrecision or 0 |
2369 | end |
2370 | end |
2371 | end |
2372 | |
2373 | spec.isInfoDirty = false |
2374 | end |
2375 | |
2376 | for _, info in ipairs(spec.fillUnitInfos) do |
2377 | local formattedNumber |
2378 | if info.precision > 0 then |
2379 | local rounded = MathUtil.round(info.fillLevel, info.precision) |
2380 | formattedNumber = string.format("%d%s%0"..info.precision.."d", math.floor(rounded), g_i18n.decimalSeparator, (rounded - math.floor(rounded)) * 10 ^ info.precision) |
2381 | else |
2382 | formattedNumber = string.format("%d", MathUtil.round(info.fillLevel)) |
2383 | end |
2384 | |
2385 | formattedNumber = formattedNumber .. " " .. (info.unit or g_i18n:getVolumeUnit()) |
2386 | |
2387 | box:addLine(info.title, formattedNumber) |
2388 | end |
2389 | |
2390 | superFunc(self, box) |
2391 | end |
unloadFillUnits
DescriptionDefinitionunloadFillUnits()Code
1175 | function FillUnit:unloadFillUnits(ignoreWarning) |
1176 | if not self.isServer then |
1177 | g_client:getServerConnection():sendEvent(FillUnitUnloadEvent.new(self)) |
1178 | else |
1179 | local spec = self.spec_fillUnit |
1180 | if spec.unloadingFillUnitsRunning then |
1181 | return |
1182 | end |
1183 | |
1184 | local unloadingPlaces = spec.unloading |
1185 | |
1186 | local places = {} |
1187 | |
1188 | for _, unloading in ipairs(unloadingPlaces) do |
1189 | local node = unloading.node |
1190 | local ox, oy, oz = unpack(unloading.offset) |
1191 | local x, y, z = localToWorld(node, ox - unloading.width*0.5, oy, oz) |
1192 | |
1193 | local place = {} |
1194 | place.startX, place.startY, place.startZ = x, y, z |
1195 | place.rotX, place.rotY, place.rotZ = getWorldRotation(node) |
1196 | place.dirX, place.dirY, place.dirZ = localDirectionToWorld(node, 1, 0, 0) |
1197 | place.dirPerpX, place.dirPerpY, place.dirPerpZ = localDirectionToWorld(node, 0, 0, 1) |
1198 | place.yOffset = 1 |
1199 | place.maxWidth = math.huge |
1200 | place.maxLength = math.huge |
1201 | place.maxHeight = math.huge |
1202 | place.width = unloading.width |
1203 | |
1204 | table.insert(places, place) |
1205 | end |
1206 | |
1207 | local usedPlaces = {} |
1208 | local success = true |
1209 | |
1210 | local availablePallets = {} |
1211 | |
1212 | local unloadingTasks = {} |
1213 | for k, fillUnit in ipairs(self:getFillUnits()) do |
1214 | local fillLevel = self:getFillUnitFillLevel(k) |
1215 | local fillTypeIndex = self:getFillUnitFillType(k) |
1216 | local fillType = g_fillTypeManager:getFillTypeByIndex(fillTypeIndex) |
1217 | if fillUnit.canBeUnloaded and fillLevel > 0 and fillType.palletFilename ~= nil then |
1218 | table.insert(unloadingTasks, {fillUnitIndex=k, fillTypeIndex=fillTypeIndex, fillLevel=fillLevel, filename=fillType.palletFilename}) |
1219 | end |
1220 | end |
1221 | |
1222 | local function unloadNext() |
1223 | local task = unloadingTasks[1] |
1224 | if task ~= nil then |
1225 | -- try to fill existing pallets |
1226 | for pallet, _ in pairs(availablePallets) do |
1227 | local fillUnitIndex = pallet:getFirstValidFillUnitToFill(task.fillTypeIndex) |
1228 | if fillUnitIndex ~= nil then |
1229 | local appliedDelta = pallet:addFillUnitFillLevel(self:getOwnerFarmId(), fillUnitIndex, task.fillLevel, task.fillTypeIndex, ToolType.UNDEFINED, nil) |
1230 | self:addFillUnitFillLevel(self:getOwnerFarmId(), task.fillUnitIndex, -appliedDelta, task.fillTypeIndex, ToolType.UNDEFINED, nil) |
1231 | task.fillLevel = task.fillLevel - appliedDelta |
1232 | |
1233 | -- remove filled pallets |
1234 | if pallet:getFillUnitFreeCapacity(fillUnitIndex) <= 0 then |
1235 | availablePallets[pallet] = nil |
1236 | end |
1237 | end |
1238 | end |
1239 | |
1240 | if task.fillLevel > 0 then |
1241 | local asyncCallback = function(_, vehicle, vehicleLoadState, arguments) |
1242 | if vehicleLoadState == VehicleLoadingUtil.VEHICLE_LOAD_OK then |
1243 | vehicle:emptyAllFillUnits(true) |
1244 | availablePallets[vehicle] = true |
1245 | unloadNext() |
1246 | end |
1247 | end |
1248 | |
1249 | |
1250 | local size = StoreItemUtil.getSizeValues(task.filename, "vehicle", 0, {}) |
1251 | local x, y, z, place, width, _ = PlacementUtil.getPlace(places, size, usedPlaces, true, true, true) |
1252 | |
1253 | if x == nil then |
1254 | success = false |
1255 | |
1256 | if ignoreWarning == nil or not ignoreWarning then |
1257 | if not success then |
1258 | g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_INFO, spec.texts.unloadNoSpace) |
1259 | end |
1260 | end |
1261 | |
1262 | return |
1263 | end |
1264 | |
1265 | PlacementUtil.markPlaceUsed(usedPlaces, place, width) |
1266 | local location = {x=x, y=y, z=z, yRot=place.rotY} |
1267 | |
1268 | VehicleLoadingUtil.loadVehicle(task.filename, location, true, 0, Vehicle.PROPERTY_STATE_OWNED, self:getOwnerFarmId(), nil, nil, asyncCallback, nil) |
1269 | else |
1270 | table.remove(unloadingTasks, 1) |
1271 | unloadNext() |
1272 | end |
1273 | end |
1274 | end |
1275 | |
1276 | unloadNext() |
1277 | end |
1278 | end |
updateAlarmTriggers
DescriptionDefinitionupdateAlarmTriggers()Code
1068 | function FillUnit:updateAlarmTriggers(alarmTriggers) |
1069 | for _, alarmTrigger in pairs(alarmTriggers) do |
1070 | self:setAlarmTriggerState(alarmTrigger, self:getAlarmTriggerIsActive(alarmTrigger)) |
1071 | end |
1072 | end |
updateFillTypeMaterials
DescriptionDefinitionupdateFillTypeMaterials()Code
1992 | function FillUnit:updateFillTypeMaterials(fillTypeMaterials, fillTypeIndex) |
1993 | for i=1, #fillTypeMaterials do |
1994 | local fillTypeMaterial = fillTypeMaterials[i] |
1995 | if fillTypeMaterial.fillTypeIndex == fillTypeIndex then |
1996 | local materialId = getMaterial(fillTypeMaterial.refNode, 0) |
1997 | setMaterial(fillTypeMaterial.node, materialId, 0) |
1998 | end |
1999 | end |
2000 | end |
updateFillUnitAutoAimTarget
DescriptionDefinitionupdateFillUnitAutoAimTarget()Code
2004 | function FillUnit:updateFillUnitAutoAimTarget(fillUnit) |
2005 | local autoAimTarget = fillUnit.autoAimTarget |
2006 | if autoAimTarget.node ~= nil then |
2007 | if autoAimTarget.startZ ~= nil and autoAimTarget.endZ ~= nil then |
2008 | local startFillLevel = fillUnit.capacity * autoAimTarget.startPercentage |
2009 | local percent = MathUtil.clamp((fillUnit.fillLevel-startFillLevel) / (fillUnit.capacity-startFillLevel), 0, 1) |
2010 | if autoAimTarget.invert then |
2011 | percent = 1 - percent |
2012 | end |
2013 | local newZ = (autoAimTarget.endZ-autoAimTarget.startZ) * percent + autoAimTarget.startZ |
2014 | setTranslation(autoAimTarget.node, autoAimTarget.baseTrans[1], autoAimTarget.baseTrans[2], newZ) |
2015 | end |
2016 | end |
2017 | end |
updateFillUnitFillPlane
DescriptionDefinitionupdateFillUnitFillPlane()Code
1920 | function FillUnit:updateFillUnitFillPlane(fillUnit) |
1921 | local fillPlane = fillUnit.fillPlane |
1922 | if fillPlane ~= nil then |
1923 | local t = self:getFillUnitFillLevelPercentage(fillUnit.fillUnitIndex) |
1924 | |
1925 | for _, node in ipairs(fillPlane.nodes) do |
1926 | local x,y,z, rx,ry,rz, sx,sy,sz = node.animCurve:get(t) |
1927 | |
1928 | setTranslation(node.node, x, y, z) |
1929 | setRotation(node.node, rx, ry, rz) |
1930 | setScale(node.node, sx, sy, sz) |
1931 | setVisibility(node.node, fillUnit.fillLevel > 0 or node.alwaysVisible) |
1932 | end |
1933 | |
1934 | --assign new material on fill type change |
1935 | if fillUnit.fillType ~= fillUnit.lastFillPlaneType then |
1936 | if fillUnit.fillType ~= FillType.UNKNOWN then |
1937 | local usedFillType = fillUnit.fillType |
1938 | if fillPlane.forcedFillType ~= nil then |
1939 | usedFillType = fillPlane.forcedFillType |
1940 | end |
1941 | |
1942 | local material = g_materialManager:getMaterial(usedFillType, "fillplane", 1) |
1943 | if material == nil and fillPlane.defaultFillType ~= nil then |
1944 | material = g_materialManager:getMaterial(fillPlane.defaultFillType, "fillplane", 1) |
1945 | end |
1946 | |
1947 | if material ~= nil then |
1948 | for _, node in ipairs(fillPlane.nodes) do |
1949 | setMaterial(node.node, material, 0) |
1950 | end |
1951 | end |
1952 | end |
1953 | |
1954 | fillUnit.lastFillPlaneType = fillUnit.fillType |
1955 | end |
1956 | end |
1957 | end |
updateFillUnitTriggers
DescriptionDefinitionupdateFillUnitTriggers()Code
2067 | function FillUnit:updateFillUnitTriggers() |
2068 | local spec = self.spec_fillUnit |
2069 | |
2070 | table.sort(spec.fillTrigger.triggers, function(t1, t2) |
2071 | local fillTypeIndex1 = t1:getCurrentFillType() |
2072 | local fillTypeIndex2 = t2:getCurrentFillType() |
2073 | |
2074 | local t1FillUnitIndex = self:getFirstValidFillUnitToFill(fillTypeIndex1) |
2075 | local t2FillUnitIndex = self:getFirstValidFillUnitToFill(fillTypeIndex2) |
2076 | |
2077 | if t1FillUnitIndex ~= nil and t2FillUnitIndex ~= nil then |
2078 | return self:getFillUnitFillLevel(t1FillUnitIndex) > self:getFillUnitFillLevel(t2FillUnitIndex) |
2079 | elseif t1FillUnitIndex ~= nil then |
2080 | return true |
2081 | end |
2082 | |
2083 | return false |
2084 | end) |
2085 | |
2086 | if #spec.fillTrigger.triggers > 0 then |
2087 | local fillTypeIndex = spec.fillTrigger.triggers[1]:getCurrentFillType() |
2088 | spec.fillTrigger.activatable:setFillType(fillTypeIndex) |
2089 | |
2090 | if spec.fillTrigger.selectedTrigger ~= spec.fillTrigger.triggers[1] then |
2091 | SpecializationUtil.raiseEvent(self, "onFillUnitTriggerChanged", spec.fillTrigger.triggers[1], fillTypeIndex, self:getFirstValidFillUnitToFill(fillTypeIndex), #spec.fillTrigger.triggers) |
2092 | |
2093 | spec.fillTrigger.selectedTrigger = spec.fillTrigger.triggers[1] |
2094 | end |
2095 | else |
2096 | spec.fillTrigger.selectedTrigger = nil |
2097 | end |
2098 | end |
updateMeasurementNodes
DescriptionDefinitionupdateMeasurementNodes()Code
1790 | function FillUnit:updateMeasurementNodes(fillUnit, dt, setActive, forcedIntensity) |
1791 | if fillUnit.measurementNodes ~= nil then |
1792 | for _, measurementNode in pairs(fillUnit.measurementNodes) do |
1793 | if setActive ~= nil and setActive then |
1794 | measurementNode.measurementTime = 5000 |
1795 | end |
1796 | |
1797 | if measurementNode.measurementTime > 0 then |
1798 | measurementNode.measurementTime = math.max(measurementNode.measurementTime - dt, 0) |
1799 | end |
1800 | |
1801 | local intensity = math.min(measurementNode.measurementTime / 5000, 1) |
1802 | intensity = math.max(intensity, math.min(self.lastSpeed * 3600 / 10, 1)) |
1803 | intensity = forcedIntensity or intensity |
1804 | if intensity ~= measurementNode.intensity then |
1805 | setShaderParameter(measurementNode.node, "fillLevel", fillUnit.fillLevel / fillUnit.capacity, intensity, 0, 0, false) |
1806 | setShaderParameter(measurementNode.node, "prevFillLevel", fillUnit.fillLevel / fillUnit.capacity, measurementNode.intensity, 0, 0, false) |
1807 | measurementNode.intensity = intensity |
1808 | end |
1809 | end |
1810 | end |
1811 | end |
updateUnloadActionDisplay
DescriptionDefinitionupdateUnloadActionDisplay()Code
2894 | function FillUnit.updateUnloadActionDisplay(self) |
2895 | local spec = self.spec_fillUnit |
2896 | if spec.unloading ~= nil then |
2897 | local isActive = false |
2898 | for k, fillUnit in ipairs(self:getFillUnits()) do |
2899 | local fillLevel = self:getFillUnitFillLevel(k) |
2900 | local fillTypeIndex = self:getFillUnitFillType(k) |
2901 | local fillType = g_fillTypeManager:getFillTypeByIndex(fillTypeIndex) |
2902 | if fillUnit.canBeUnloaded and fillLevel > 0 and fillType.palletFilename ~= nil then |
2903 | isActive = true |
2904 | break |
2905 | end |
2906 | end |
2907 | |
2908 | if self.getCurrentDischargeNode ~= nil then |
2909 | local dischargeNode = self:getCurrentDischargeNode() |
2910 | if dischargeNode ~= nil then |
2911 | local dischargeObject, _ = self:getDischargeTargetObject(dischargeNode) |
2912 | if dischargeObject ~= nil then |
2913 | isActive = false |
2914 | end |
2915 | end |
2916 | end |
2917 | |
2918 | g_inputBinding:setActionEventActive(spec.unloadActionEventId, isActive) |
2919 | end |
2920 | end |