LUADOC - Farming Simulator 19

Script v1.7.1.0

Engine v1.7.1.0

Foundation Reference

FillUnit

Description
Specialization for vehicles with any sort of capacity or tank. Manages filltypes, capacities, fillLevel changes
Functions

actionEventConsoleFillUnitDec

Description
Definition
actionEventConsoleFillUnitDec()
Code
2233function FillUnit.actionEventConsoleFillUnitDec(self, actionName, inputValue, callbackState, isAnalog)
2234 if self:getIsSelected() then
2235 local fillType = self:getFillUnitFillType(1)
2236 self:addFillUnitFillLevel(self:getOwnerFarmId(), 1, -1000, fillType, ToolType.UNDEFINED, nil)
2237 end
2238end

actionEventConsoleFillUnitInc

Description
Definition
actionEventConsoleFillUnitInc()
Code
2220function FillUnit.actionEventConsoleFillUnitInc(self, actionName, inputValue, callbackState, isAnalog)
2221 if self:getIsSelected() then
2222 local fillType = self:getFillUnitFillType(1)
2223 if fillType == FillType.UNKNOWN then
2224 local fillUnit = self:getFillUnitByIndex(1)
2225 fillType = next(fillUnit.supportedFillTypes)
2226 end
2227 self:addFillUnitFillLevel(self:getOwnerFarmId(), 1, 1000, fillType, ToolType.UNDEFINED, nil)
2228 end
2229end

actionEventConsoleFillUnitNext

Description
Definition
actionEventConsoleFillUnitNext()
Code
2192function FillUnit.actionEventConsoleFillUnitNext(self, actionName, inputValue, callbackState, isAnalog)
2193 if self:getIsSelected() then
2194 local fillType = self:getFillUnitFillType(1)
2195 local fillUnit = self:getFillUnitByIndex(1)
2196 local found = false
2197 local nextFillType = nil
2198 for supportedFillType,_ in pairs(fillUnit.supportedFillTypes) do
2199 if not found then
2200 if supportedFillType == fillType then
2201 found = true
2202 end
2203 else
2204 nextFillType = supportedFillType
2205 break
2206 end
2207 end
2208
2209 if nextFillType == nil then
2210 nextFillType = next(fillUnit.supportedFillTypes)
2211 end
2212
2213 self:addFillUnitFillLevel(self:getOwnerFarmId(), 1, -math.huge, fillType, ToolType.UNDEFINED, nil)
2214 self:addFillUnitFillLevel(self:getOwnerFarmId(), 1, 100, nextFillType, ToolType.UNDEFINED, nil)
2215 end
2216end

actionEventUnload

Description
Definition
actionEventUnload()
Code
2242function FillUnit.actionEventUnload(self, actionName, inputValue, callbackState, isAnalog)
2243 self:unloadFillUnits()
2244end

addFillTypeSources

Description
Definition
addFillTypeSources()
Code
1947function FillUnit.addFillTypeSources(sources, currentVehicle, excludeVehicle, fillTypes)
1948 if currentVehicle ~= excludeVehicle then
1949 local curVehicle = currentVehicle.spec_fillUnit
1950 if curVehicle ~= nil then
1951 for fillUnitIndex2, fillUnit2 in pairs(curVehicle.fillUnits) do
1952 for _,fillType in pairs(fillTypes) do
1953 if fillUnit2.supportedFillTypes[fillType] then
1954 if sources[fillType] == nil then
1955 sources[fillType] = {}
1956 end
1957 table.insert(sources[fillType], {vehicle=currentVehicle, fillUnitIndex=fillUnitIndex2})
1958 end
1959 end
1960 end
1961 end
1962 end
1963
1964 if currentVehicle.getAttachedImplements ~= nil then
1965 local attachedImplements = currentVehicle:getAttachedImplements()
1966 for _,implement in pairs(attachedImplements) do
1967 if implement.object ~= nil then
1968 FillUnit.addFillTypeSources(sources, implement.object, excludeVehicle, fillTypes)
1969 end
1970 end
1971 end
1972end

addFillUnitFillLevel

Description
Definition
addFillUnitFillLevel()
Code
1050function FillUnit:addFillUnitFillLevel(farmId, fillUnitIndex, fillLevelDelta, fillTypeIndex, toolType, fillPositionData)
1051 local spec = self.spec_fillUnit
1052
1053 -- Check for permission. Do allow vehicles with farmId 0 (all-access vehicles).
1054 -- Only check for access if value is being removed
1055 if fillLevelDelta < 0 and not g_currentMission.accessHandler:canFarmAccess(farmId, self, true) then
1056 return 0
1057 end
1058
1059 -- If this fillunit belongs to a mounted object (pallet), check that the controller of the object
1060 -- is allowed to empty the fill unit.
1061 if self.getMountObject ~= nil then
1062 local mounter = self:getDynamicMountObject() or self:getMountObject()
1063 if mounter ~= nil then
1064 -- if the active farm of the mounter has NO access to farmId fill unit: disallow
1065 if not g_currentMission.accessHandler:canFarmAccess(mounter:getActiveFarm(), self, true) then
1066 return 0
1067 end
1068 end
1069 end
1070
1071 local fillUnit = spec.fillUnits[fillUnitIndex]
1072 if fillUnit ~= nil then
1073 if not self:getFillUnitSupportsToolTypeAndFillType(fillUnitIndex, toolType, fillTypeIndex) then
1074 return 0
1075 end
1076
1077 local oldFillLevel = fillUnit.fillLevel
1078 local capacity = fillUnit.capacity
1079 if capacity == 0 then
1080 capacity = math.huge
1081 end
1082
1083 if fillUnit.fillType == fillTypeIndex then
1084 fillUnit.fillLevel = math.max(0, math.min(capacity, oldFillLevel + fillLevelDelta))
1085 else
1086 if fillLevelDelta > 0 then
1087 local allowFillType = self:getFillUnitAllowsFillType(fillUnitIndex, fillTypeIndex)
1088 if allowFillType then
1089 local oldFillTypeIndex = fillUnit.fillType
1090 if oldFillLevel > 0 then
1091 self:addFillUnitFillLevel(farmId, fillUnitIndex, -math.huge, fillUnit.fillType, toolType, fillPositionData)
1092 end
1093 oldFillLevel = 0
1094 fillUnit.fillLevel = math.max(0, math.min(capacity, fillLevelDelta))
1095 fillUnit.fillType = fillTypeIndex
1096
1097 self:getRootVehicle():raiseStateChange(Vehicle.STATE_CHANGE_FILLTYPE_CHANGE)
1098 SpecializationUtil.raiseEvent(self, "onChangedFillType", fillUnitIndex, fillTypeIndex, oldFillTypeIndex)
1099 else
1100 return 0
1101 end
1102 end
1103 end
1104
1105 if fillUnit.fillLevel > 0 then
1106 fillUnit.lastValidFillType = fillUnit.fillType
1107 else
1108 SpecializationUtil.raiseEvent(self, "onChangedFillType", fillUnitIndex, FillType.UNKNOWN, fillUnit.fillType)
1109 fillUnit.fillType = FillType.UNKNOWN
1110
1111 if not fillUnit.fillTypeToDisplayIsPersistent then
1112 fillUnit.fillTypeToDisplay = FillType.UNKNOWN
1113 end
1114
1115 if not fillUnit.fillLevelToDisplayIsPersistent then
1116 fillUnit.fillLevelToDisplay = nil
1117 end
1118 end
1119
1120 local appliedDelta = fillUnit.fillLevel - oldFillLevel
1121
1122 if self.isServer then
1123 -- prepare for network
1124 if fillUnit.synchronizeFillLevel then
1125 local hasChanged = false
1126 if fillUnit.fillLevel ~= fillUnit.fillLevelSent then
1127 local maxValue = 2^fillUnit.synchronizationNumBits - 1
1128 local levelPerBit = fillUnit.capacity / maxValue
1129 local changedLevel = math.abs(fillUnit.fillLevel - fillUnit.fillLevelSent)
1130
1131 if changedLevel > levelPerBit then
1132 fillUnit.fillLevelSent = fillUnit.fillLevel
1133 hasChanged = true
1134 end
1135 end
1136 if fillUnit.fillType ~= fillUnit.fillTypeSent then
1137 fillUnit.fillTypeSent = fillUnit.fillType
1138 hasChanged = true
1139 end
1140 if fillUnit.lastValidFillType ~= fillUnit.lastValidFillTypeSent then
1141 fillUnit.lastValidFillTypeSent = fillUnit.lastValidFillType
1142 hasChanged = true
1143 end
1144 if hasChanged then
1145 self:raiseDirtyFlags(spec.dirtyFlag)
1146 end
1147 end
1148 end
1149
1150 if fillUnit.updateMass then
1151 self:setMassDirty()
1152 end
1153
1154 self:updateFillUnitAutoAimTarget(fillUnit)
1155
1156 if self.isClient then
1157 self:updateAlarmTriggers(fillUnit.alarmTriggers)
1158 self:updateFillUnitFillPlane(fillUnit)
1159 self:updateMeasurementNodes(fillUnit, 0, true)
1160 end
1161
1162 SpecializationUtil.raiseEvent(self, "onFillUnitFillLevelChanged", fillUnitIndex, fillLevelDelta, fillTypeIndex, toolType, fillPositionData, appliedDelta)
1163
1164 if self.isServer then
1165 if spec.removeVehicleIfEmpty and fillUnit.fillLevel <= 0.3 then
1166 g_currentMission:removeVehicle(self)
1167 end
1168 end
1169
1170 if appliedDelta > 0 then
1171 -- display default effects
1172 if #spec.fillEffects > 0 then
1173 g_effectManager:setFillType(spec.fillEffects, fillUnit.fillType)
1174 g_effectManager:startEffects(spec.fillEffects)
1175
1176 spec.activeFillEffects[spec.fillEffects] = 500
1177 end
1178
1179 -- display fill unit effects
1180 if #fillUnit.fillEffects > 0 then
1181 g_effectManager:setFillType(fillUnit.fillEffects, fillUnit.fillType)
1182 g_effectManager:startEffects(fillUnit.fillEffects)
1183
1184 spec.activeFillEffects[fillUnit.fillEffects] = 500
1185 end
1186
1187
1188 -- start default animation nodes
1189 if #spec.animationNodes > 0 then
1190 g_animationManager:startAnimations(spec.animationNodes)
1191 spec.activeFillAnimations[spec.animationNodes] = 500
1192 end
1193
1194 -- start fill unit animation nodes
1195 if #fillUnit.animationNodes > 0 then
1196 g_animationManager:startAnimations(fillUnit.animationNodes)
1197 spec.activeFillAnimations[fillUnit.animationNodes] = 500
1198 end
1199
1200 if fillUnit.fillAnimation ~= nil then
1201 if fillUnit.fillAnimationLoadTime ~= nil then
1202 local animTime = self:getAnimationTime(fillUnit.fillAnimation)
1203 local direction = MathUtil.sign(fillUnit.fillAnimationLoadTime-animTime)
1204 if direction ~= 0 then
1205 self:playAnimation(fillUnit.fillAnimation, direction, animTime)
1206 self:setAnimationStopTime(fillUnit.fillAnimation, fillUnit.fillAnimationLoadTime)
1207 end
1208 end
1209 end
1210 end
1211
1212 if fillUnit.fillLevel < 0.0001 then
1213 if fillUnit.fillAnimation ~= nil then
1214 if fillUnit.fillAnimationEmptyTime ~= nil then
1215 local animTime = self:getAnimationTime(fillUnit.fillAnimation)
1216 local direction = MathUtil.sign(fillUnit.fillAnimationEmptyTime-animTime)
1217 self:playAnimation(fillUnit.fillAnimation, direction, animTime)
1218 self:setAnimationStopTime(fillUnit.fillAnimation, fillUnit.fillAnimationEmptyTime)
1219 end
1220 end
1221 end
1222
1223 if self.setDashboardsDirty ~= nil then
1224 self:setDashboardsDirty()
1225 end
1226
1227 FillUnit.updateUnloadActionDisplay(self)
1228
1229 return appliedDelta
1230 end
1231
1232 return 0
1233end

addFillUnitTrigger

Description
Adds fill trigger
Definition
addFillUnitTrigger(table trigger, integer fillTypeIndex)
Arguments
tabletriggertrigger
integerfillTypeIndexfillTypeIndex
Code
1673function FillUnit:addFillUnitTrigger(trigger, fillTypeIndex, fillUnitIndex)
1674 local spec = self.spec_fillUnit
1675 if #spec.fillTrigger.triggers == 0 then
1676 g_currentMission:addActivatableObject(spec.fillTrigger.activatable)
1677 spec.fillTrigger.activatable:setFillType(fillTypeIndex)
1678 end
1679 ListUtil.addElementToList(spec.fillTrigger.triggers, trigger)
1680 SpecializationUtil.raiseEvent(self, "onAddedFillUnitTrigger", fillTypeIndex, fillUnitIndex, #spec.fillTrigger.triggers)
1681end

addNodeObjectMapping

Description
Definition
addNodeObjectMapping()
Code
1809function FillUnit:addNodeObjectMapping(superFunc, list)
1810 superFunc(self, list)
1811
1812 local spec = self.spec_fillUnit
1813
1814 for _,fillUnit in pairs(spec.fillUnits) do
1815 if fillUnit.fillRootNode ~= nil then
1816 list[fillUnit.fillRootNode] = self
1817 end
1818 if fillUnit.exactFillRootNode ~= nil then
1819 list[fillUnit.exactFillRootNode] = self
1820 end
1821 end
1822end

emptyAllFillUnits

Description
Definition
emptyAllFillUnits()
Code
938function FillUnit:emptyAllFillUnits(ignoreDeleteOnEmptyFlag)
939 local spec = self.spec_fillUnit
940 local oldRemoveOnEmpty = spec.removeVehicleIfEmpty
941 if ignoreDeleteOnEmptyFlag then
942 spec.removeVehicleIfEmpty = false
943 end
944
945 for k, _ in ipairs(self:getFillUnits()) do
946 local fillTypeIndex = self:getFillUnitFillType(k)
947 self:addFillUnitFillLevel(self:getOwnerFarmId(), k, -math.huge, fillTypeIndex, ToolType.UNDEFINED, nil)
948 end
949
950 spec.removeVehicleIfEmpty = oldRemoveOnEmpty
951end

getAdditionalComponentMass

Description
Definition
getAdditionalComponentMass()
Code
1792function FillUnit:getAdditionalComponentMass(superFunc, component)
1793 local additionalMass = superFunc(self, component)
1794 local spec = self.spec_fillUnit
1795
1796 for _, fillUnit in ipairs(spec.fillUnits) do
1797 if fillUnit.updateMass and fillUnit.fillMassNode == component.node and fillUnit.fillType ~= nil and fillUnit.fillType ~= FillType.UNKNOWN then
1798 local desc = g_fillTypeManager:getFillTypeByIndex(fillUnit.fillType)
1799 local mass = fillUnit.fillLevel * desc.massPerLiter
1800 additionalMass = additionalMass + mass
1801 end
1802 end
1803
1804 return additionalMass
1805end

getAlarmTriggerIsActive

Description
Definition
getAlarmTriggerIsActive()
Code
875function FillUnit:getAlarmTriggerIsActive(alarmTrigger)
876 local ret = false
877
878 local fillLevelPct = alarmTrigger.fillUnit.fillLevel / alarmTrigger.fillUnit.capacity
879 if fillLevelPct >= alarmTrigger.minFillLevel and fillLevelPct <= alarmTrigger.maxFillLevel then
880 ret = true
881 end
882
883 return ret
884end

getDoConsumePtoPower

Description
Definition
getDoConsumePtoPower()
Code
1933function FillUnit:getDoConsumePtoPower(superFunc)
1934 local fillTrigger = self.spec_fillUnit.fillTrigger
1935 return superFunc(self) or (fillTrigger.isFilling and fillTrigger.consumePtoPower)
1936end

getDrawFirstFillText

Description
Definition
getDrawFirstFillText()
Code
582function FillUnit:getDrawFirstFillText()
583 return false
584end

getFillLevelInformation

Description
Get fill level information
Definition
getFillLevelInformation(table fillLevelInformations)
Arguments
tablefillLevelInformationsfill level informations
Code
1844function FillUnit:getFillLevelInformation(superFunc, fillLevelInformations)
1845 superFunc(self, fillLevelInformations)
1846
1847 local spec = self.spec_fillUnit
1848 for _,fillUnit in pairs(spec.fillUnits) do
1849 if fillUnit.capacity > 0 and fillUnit.showOnHud then
1850 local fillType = fillUnit.fillType
1851 if fillUnit.fillTypeToDisplay ~= FillType.UNKNOWN then
1852 fillType = fillUnit.fillTypeToDisplay
1853 end
1854
1855 local fillLevel = fillUnit.fillLevel
1856 if fillUnit.fillLevelToDisplay ~= nil then
1857 fillLevel = fillUnit.fillLevelToDisplay
1858 end
1859
1860 local added = false
1861 for _,fillLevelInformation in pairs(fillLevelInformations) do
1862 if fillLevelInformation.fillType == fillType then
1863 fillLevelInformation.fillLevel = fillLevelInformation.fillLevel + fillLevel
1864 fillLevelInformation.capacity = fillLevelInformation.capacity + fillUnit.capacity
1865 added = true
1866 break
1867 end
1868 end
1869 if not added then
1870 table.insert(fillLevelInformations, {fillType=fillType, fillLevel=fillLevel, capacity=fillUnit.capacity})
1871 end
1872 end
1873 end
1874end

getFillTypeChangeThreshold

Description
Definition
getFillTypeChangeThreshold()
Code
775function FillUnit:getFillTypeChangeThreshold(fillUnitIndex)
776 if fillUnitIndex == nil then
777 return self.spec_fillUnit.fillTypeChangeThreshold
778 else
779 local capacity = self:getFillUnitCapacity(fillUnitIndex) or 1
780 return capacity * self.spec_fillUnit.fillTypeChangeThreshold
781 end
782end

getFillUnitAllowsFillType

Description
Definition
getFillUnitAllowsFillType()
Code
759function FillUnit:getFillUnitAllowsFillType(fillUnitIndex, fillType)
760 local spec = self.spec_fillUnit
761 if spec.fillUnits[fillUnitIndex] ~= nil then
762 if self:getFillUnitSupportsFillType(fillUnitIndex, fillType) then
763 if fillType == spec.fillUnits[fillUnitIndex].fillType then
764 return true
765 else
766 return (spec.fillUnits[fillUnitIndex].fillLevel / math.max(spec.fillUnits[fillUnitIndex].capacity, 0.0001)) <= self:getFillTypeChangeThreshold()
767 end
768 end
769 end
770 return false
771end

getFillUnitAutoAimTargetNode

Description
Definition
getFillUnitAutoAimTargetNode()
Code
702function FillUnit:getFillUnitAutoAimTargetNode(fillUnitIndex)
703 local spec = self.spec_fillUnit
704 if spec.fillUnits[fillUnitIndex] ~= nil then
705 return spec.fillUnits[fillUnitIndex].autoAimTarget.node
706 end
707 return nil
708end

getFillUnitByIndex

Description
Definition
getFillUnitByIndex()
Code
595function FillUnit:getFillUnitByIndex(fillUnitIndex)
596 local spec = self.spec_fillUnit
597 if self:getFillUnitExists(fillUnitIndex) then
598 return spec.fillUnits[fillUnitIndex]
599 end
600 return nil
601end

getFillUnitCapacity

Description
Definition
getFillUnitCapacity()
Code
612function FillUnit:getFillUnitCapacity(fillUnitIndex)
613 local spec = self.spec_fillUnit
614 if spec.fillUnits[fillUnitIndex] ~= nil then
615 return spec.fillUnits[fillUnitIndex].capacity
616 end
617 return nil
618end

getFillUnitExactFillRootNode

Description
Definition
getFillUnitExactFillRootNode()
Code
682function FillUnit:getFillUnitExactFillRootNode(fillUnitIndex)
683 local spec = self.spec_fillUnit
684 if spec.fillUnits[fillUnitIndex] ~= nil then
685 return spec.fillUnits[fillUnitIndex].exactFillRootNode
686 end
687 return nil
688end

getFillUnitExists

Description
Definition
getFillUnitExists()
Code
605function FillUnit:getFillUnitExists(fillUnitIndex)
606 local spec = self.spec_fillUnit
607 return fillUnitIndex ~= nil and spec.fillUnits[fillUnitIndex] ~= nil
608end

getFillUnitExtraDistanceFromNode

Description
Definition
getFillUnitExtraDistanceFromNode()
Code
924function FillUnit:getFillUnitExtraDistanceFromNode(node)
925 local spec = self.spec_fillUnit
926 return spec.exactFillRootNodeToExtraDistance[node] or 0
927end

getFillUnitFillLevel

Description
Definition
getFillUnitFillLevel()
Code
632function FillUnit:getFillUnitFillLevel(fillUnitIndex)
633 local spec = self.spec_fillUnit
634 if spec.fillUnits[fillUnitIndex] ~= nil then
635 return spec.fillUnits[fillUnitIndex].fillLevel
636 end
637 return nil
638end

getFillUnitFillLevelPercentage

Description
Definition
getFillUnitFillLevelPercentage()
Code
642function FillUnit:getFillUnitFillLevelPercentage(fillUnitIndex)
643 local spec = self.spec_fillUnit
644 if spec.fillUnits[fillUnitIndex] ~= nil then
645 return spec.fillUnits[fillUnitIndex].fillLevel / spec.fillUnits[fillUnitIndex].capacity
646 end
647 return nil
648end

getFillUnitFillType

Description
Definition
getFillUnitFillType()
Code
652function FillUnit:getFillUnitFillType(fillUnitIndex)
653 local spec = self.spec_fillUnit
654 if spec.fillUnits[fillUnitIndex] ~= nil then
655 return spec.fillUnits[fillUnitIndex].fillType
656 end
657 return nil
658end

getFillUnitFirstSupportedFillType

Description
Definition
getFillUnitFirstSupportedFillType()
Code
672function FillUnit:getFillUnitFirstSupportedFillType(fillUnitIndex)
673 local spec = self.spec_fillUnit
674 if spec.fillUnits[fillUnitIndex] ~= nil then
675 return next(spec.fillUnits[fillUnitIndex].supportedFillTypes)
676 end
677 return nil
678end

getFillUnitForcedMaterialFillType

Description
Definition
getFillUnitForcedMaterialFillType()
Code
856function FillUnit:getFillUnitForcedMaterialFillType(fillUnitIndex)
857 local spec = self.spec_fillUnit
858 if spec.fillUnits[fillUnitIndex] ~= nil then
859 return spec.fillUnits[fillUnitIndex].forcedMaterialFillType
860 end
861
862 return FillType.UNKNOWN
863end

getFillUnitFreeCapacity

Description
Definition
getFillUnitFreeCapacity()
Code
622function FillUnit:getFillUnitFreeCapacity(fillUnitIndex, fillTypeIndex, farmId)
623 local spec = self.spec_fillUnit
624 if spec.fillUnits[fillUnitIndex] ~= nil then
625 return spec.fillUnits[fillUnitIndex].capacity - spec.fillUnits[fillUnitIndex].fillLevel
626 end
627 return nil
628end

getFillUnitFromNode

Description
Definition
getFillUnitFromNode()
Code
931function FillUnit:getFillUnitFromNode(node)
932 local spec = self.spec_fillUnit
933 return spec.exactFillRootNodeToFillUnit[node]
934end

getFillUnitIndexFromNode

Description
Definition
getFillUnitIndexFromNode()
Code
912function FillUnit:getFillUnitIndexFromNode(node)
913 local spec = self.spec_fillUnit
914 local fillUnit = spec.exactFillRootNodeToFillUnit[node]
915 if fillUnit ~= nil then
916 return fillUnit.fillUnitIndex
917 end
918
919 return nil
920end

getFillUnitLastValidFillType

Description
Definition
getFillUnitLastValidFillType()
Code
662function FillUnit:getFillUnitLastValidFillType(fillUnitIndex)
663 local spec = self.spec_fillUnit
664 if spec.fillUnits[fillUnitIndex] ~= nil then
665 return spec.fillUnits[fillUnitIndex].lastValidFillType
666 end
667 return nil
668end

getFillUnitRootNode

Description
Definition
getFillUnitRootNode()
Code
692function FillUnit:getFillUnitRootNode(fillUnitIndex)
693 local spec = self.spec_fillUnit
694 if spec.fillUnits[fillUnitIndex] ~= nil then
695 return spec.fillUnits[fillUnitIndex].fillRootNode
696 end
697 return nil
698end

getFillUnits

Description
Definition
getFillUnits()
Code
588function FillUnit:getFillUnits()
589 local spec = self.spec_fillUnit
590 return spec.fillUnits
591end

getFillUnitSupportedFillTypes

Description
Definition
getFillUnitSupportedFillTypes()
Code
739function FillUnit:getFillUnitSupportedFillTypes(fillUnitIndex)
740 local spec = self.spec_fillUnit
741 if spec.fillUnits[fillUnitIndex] ~= nil then
742 return spec.fillUnits[fillUnitIndex].supportedFillTypes
743 end
744 return nil
745end

getFillUnitSupportedToolTypes

Description
Definition
getFillUnitSupportedToolTypes()
Code
749function FillUnit:getFillUnitSupportedToolTypes(fillUnitIndex)
750 local spec = self.spec_fillUnit
751 if spec.fillUnits[fillUnitIndex] ~= nil then
752 return spec.fillUnits[fillUnitIndex].supportedToolTypes
753 end
754 return nil
755end

getFillUnitSupportsFillType

Description
Definition
getFillUnitSupportsFillType()
Code
712function FillUnit:getFillUnitSupportsFillType(fillUnitIndex, fillType)
713 local spec = self.spec_fillUnit
714 if spec.fillUnits[fillUnitIndex] ~= nil then
715 return spec.fillUnits[fillUnitIndex].supportedFillTypes[fillType]
716 end
717 return false
718end

getFillUnitSupportsToolType

Description
Definition
getFillUnitSupportsToolType()
Code
722function FillUnit:getFillUnitSupportsToolType(fillUnitIndex, toolType)
723 local spec = self.spec_fillUnit
724 if spec.fillUnits[fillUnitIndex] ~= nil then
725 return spec.fillUnits[fillUnitIndex].supportedToolTypes[toolType]
726 end
727 return false
728end

getFillUnitSupportsToolTypeAndFillType

Description
Definition
getFillUnitSupportsToolTypeAndFillType()
Code
732function FillUnit:getFillUnitSupportsToolTypeAndFillType(fillUnitIndex, toolType, fillType)
733 return self:getFillUnitSupportsToolType(fillUnitIndex, toolType)
734 and self:getFillUnitSupportsFillType(fillUnitIndex, fillType)
735end

getFirstValidFillUnitToFill

Description
Definition
getFirstValidFillUnitToFill()
Code
786function FillUnit:getFirstValidFillUnitToFill(fillType, ignoreCapacity)
787 local spec = self.spec_fillUnit
788 for fillUnitIndex, _ in ipairs(spec.fillUnits) do
789 if self:getFillUnitAllowsFillType(fillUnitIndex, fillType) then
790 if self:getFillUnitFreeCapacity(fillUnitIndex) > 0 or (ignoreCapacity ~= nil and ignoreCapacity) then
791 return fillUnitIndex
792 end
793 end
794 end
795
796 return nil
797end

getIsFillUnitActive

Description
Definition
getIsFillUnitActive()
Code
1784function FillUnit:getIsFillUnitActive(fillUnitIndex)
1785 return true
1786end

getIsFoldAllowed

Description
Definition
getIsFoldAllowed()
Code
1878function FillUnit:getIsFoldAllowed(superFunc, direction, onAiTurnOn)
1879 local spec = self.spec_fillUnit
1880 if not spec.allowFoldingWhileFilled then
1881 for fillUnitIndex, _ in ipairs(spec.fillUnits) do
1882 if self:getFillUnitFillLevel(fillUnitIndex) > spec.allowFoldingThreshold then
1883 return false
1884 end
1885 end
1886 end
1887
1888 return superFunc(self, direction, onAiTurnOn)
1889end

getIsMovingToolActive

Description
Definition
getIsMovingToolActive()
Code
1920function FillUnit:getIsMovingToolActive(superFunc, movingTool)
1921 if movingTool.fillUnitIndex ~= nil then
1922 local fillLevelPct = self:getFillUnitFillLevelPercentage(movingTool.fillUnitIndex)
1923 if fillLevelPct > movingTool.minFillLevel or fillLevelPct < movingTool.maxFillLevel then
1924 return false
1925 end
1926 end
1927
1928 return superFunc(self, movingTool)
1929end

getIsPowerTakeOffActive

Description
Definition
getIsPowerTakeOffActive()
Code
1940function FillUnit:getIsPowerTakeOffActive(superFunc)
1941 local fillTrigger = self.spec_fillUnit.fillTrigger
1942 return superFunc(self) or (fillTrigger.isFilling and fillTrigger.consumePtoPower)
1943end

getIsReadyForAutomatedTrainTravel

Description
Definition
getIsReadyForAutomatedTrainTravel()
Code
1893function FillUnit:getIsReadyForAutomatedTrainTravel(superFunc)
1894 local spec = self.spec_fillUnit
1895 for _, fillUnit in ipairs(spec.fillUnits) do
1896 if fillUnit.blocksAutomatedTrainTravel and fillUnit.fillLevel > 0 then
1897 return false
1898 end
1899 end
1900
1901 return superFunc(self)
1902end

getSpecValueCapacity

Description
Definition
getSpecValueCapacity()
Code
2026function FillUnit.getSpecValueCapacity(storeItem, realItem, returnValues, configurations)
2027 local configurationIndex = 1
2028 if realItem ~= nil and storeItem.configurations ~= nil and realItem.configurations["fillUnit"] ~= nil and storeItem.configurations["fillUnit"] ~= nil then
2029 configurationIndex = realItem.configurations["fillUnit"]
2030 elseif configurations ~= nil and storeItem.configurations ~= nil and configurations["fillUnit"] ~= nil and storeItem.configurations["fillUnit"] ~= nil then
2031 configurationIndex = configurations["fillUnit"]
2032 end
2033
2034 local capacity = 0
2035 local unit = ""
2036
2037 local fillUnitConfigurations = storeItem.specs.capacity
2038 if fillUnitConfigurations ~= nil then
2039 if realItem ~= nil or configurations ~= nil then
2040 if fillUnitConfigurations[configurationIndex] ~= nil then
2041 for _, fillUnit in ipairs(fillUnitConfigurations[configurationIndex]) do
2042 capacity = capacity + fillUnit.capacity
2043 unit = fillUnit.unit
2044 end
2045 end
2046 else
2047 -- if no configuration index is given we use the max capacity the vehicle can have
2048 for _, configuration in ipairs(fillUnitConfigurations) do
2049 local configCapacity = 0
2050 for _, fillUnit in ipairs(configuration) do
2051 configCapacity = configCapacity + fillUnit.capacity
2052 unit = fillUnit.unit
2053 end
2054
2055 capacity = math.max(capacity, configCapacity)
2056 end
2057 end
2058 end
2059
2060 if capacity == 0 then
2061 if returnValues == nil or not returnValues then
2062 return nil
2063 end
2064 end
2065
2066 if unit ~= "" then
2067 if unit:sub(1,6) == "$l10n_" then
2068 unit = unit:sub(7)
2069 end
2070 end
2071
2072 if returnValues == nil or not returnValues then
2073 return string.format(g_i18n:getText("shop_capacityValue"), capacity, g_i18n:getText(unit or "unit_literShort"))
2074 else
2075 return capacity, unit
2076 end
2077end

getSpecValueFillTypes

Description
Definition
getSpecValueFillTypes()
Code
2163function FillUnit.getSpecValueFillTypes(storeItem, realItem)
2164 local specs = storeItem.specs.fillTypes
2165 if specs ~= nil then
2166 if specs.categoryNames ~= nil then
2167 return g_fillTypeManager:getFillTypesByCategoryNames(specs.categoryNames, nil)
2168 elseif specs.fillTypeNames ~= nil then
2169 return g_fillTypeManager:getFillTypesByNames(specs.fillTypeNames, nil)
2170 elseif specs.fruitTypeNames ~= nil then
2171 return g_fruitTypeManager:getFillTypesByFruitTypeNames(specs.fruitTypeNames, nil)
2172 elseif specs.fruitTypeCategoryNames ~= nil then
2173 if specs.useWindrowed then
2174 local fruitTypes = g_fruitTypeManager:getFruitTypesByCategoryNames(specs.fruitTypeCategoryNames, "Warning: Cutter has invalid fruitTypeCategory '%s'.")
2175 local windrowFillTypes = {}
2176
2177 for _, fruitType in pairs(fruitTypes) do
2178 table.insert(windrowFillTypes, g_fruitTypeManager:getWindrowFillTypeIndexByFruitTypeIndex(fruitType))
2179 end
2180
2181 return windrowFillTypes
2182 else
2183 return g_fruitTypeManager:getFillTypesByFruitTypeCategoryName(specs.fruitTypeCategoryNames, nil)
2184 end
2185 end
2186 end
2187 return nil
2188end

initSpecialization

Description
Definition
initSpecialization()
Code
25function FillUnit.initSpecialization()
26 Vehicle.registerStateChange("FILLTYPE_CHANGE")
27
28 g_configurationManager:addConfigurationType("fillUnit", g_i18n:getText("configuration_fillUnit"), "fillUnit", nil, nil, nil, ConfigurationUtil.SELECTOR_MULTIOPTION)
29
30 g_storeManager:addSpecType("capacity", "shopListAttributeIconCapacity", FillUnit.loadSpecValueCapacity, FillUnit.getSpecValueCapacity)
31 g_storeManager:addSpecType("fillTypes", "shopListAttributeIconFillTypes", FillUnit.loadSpecValueFillTypes, FillUnit.getSpecValueFillTypes)
32end

loadAlarmTrigger

Description
Definition
loadAlarmTrigger()
Code
1446function FillUnit:loadAlarmTrigger(xmlFile, key, alarmTrigger, fillUnit)
1447 alarmTrigger.fillUnit = fillUnit
1448 alarmTrigger.isActive = false
1449
1450 local success = true
1451 alarmTrigger.minFillLevel = getXMLFloat(xmlFile, key .. "#minFillLevel")
1452 if alarmTrigger.minFillLevel == nil then
1453 g_logManager:xmlWarning(self.configFileName, "Missing 'minFillLevel' for alarmTrigger '%s'", key)
1454 success = false
1455 end
1456
1457 alarmTrigger.maxFillLevel = getXMLFloat(xmlFile, key .. "#maxFillLevel")
1458 if alarmTrigger.maxFillLevel == nil then
1459 g_logManager:xmlWarning(self.configFileName, "Missing 'maxFillLevel' for alarmTrigger '%s'", key)
1460 success = false
1461 end
1462
1463 alarmTrigger.sample = g_soundManager:loadSampleFromXML(xmlFile, key, "alarmSound", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self)
1464
1465 return success
1466end

loadFillPlane

Description
Definition
loadFillPlane()
Code
1509function FillUnit:loadFillPlane(xmlFile, key, fillPlane, fillUnit)
1510 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key.."#fillType", "Material is dynamically assigned to the nodes")
1511
1512 if not hasXMLProperty(xmlFile, key) then
1513 return false
1514 end
1515
1516 fillPlane.nodes = {}
1517 local i = 0
1518 while true do
1519 local nodeKey = string.format("%s.node(%d)", key, i)
1520 if not hasXMLProperty(xmlFile, nodeKey) then
1521 break
1522 end
1523
1524 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, nodeKey.."#index", nodeKey.."#node") -- FS17 to FS19
1525
1526 local node = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, nodeKey.."#node"), self.i3dMappings)
1527 if node ~= nil then
1528 local defaultX, defaultY, defaultZ = getTranslation(node)
1529 local defaultRX, defaultRY, defaultRZ = getRotation(node)
1530
1531 local animCurve = AnimCurve:new(linearInterpolatorTransRotScale)
1532 local j = 0
1533 while true do
1534 local animKey = string.format("%s.key(%d)", nodeKey, j)
1535 if not hasXMLProperty(xmlFile, animKey) then
1536 break
1537 end
1538
1539 local keyTime = getXMLFloat(xmlFile, animKey.."#time")
1540 if keyTime == nil then
1541 break
1542 end
1543
1544 local x,y,z = StringUtil.getVectorFromString(getXMLString(xmlFile, animKey.."#translation"))
1545 if y == nil then
1546 y = getXMLFloat(xmlFile, animKey.."#y")
1547 end
1548 x = Utils.getNoNil(x, defaultX)
1549 y = Utils.getNoNil(y, defaultY)
1550 z = Utils.getNoNil(z, defaultZ)
1551
1552 local rx,ry,rz = StringUtil.getVectorFromString(getXMLString(xmlFile, animKey.."#rotation"))
1553 rx = Utils.getNoNilRad(rx, defaultRX)
1554 ry = Utils.getNoNilRad(ry, defaultRY)
1555 rz = Utils.getNoNilRad(rz, defaultRZ)
1556
1557 local sx,sy,sz = StringUtil.getVectorFromString(getXMLString(xmlFile, animKey.."#scale"))
1558 sx = Utils.getNoNil(sx, 1)
1559 sy = Utils.getNoNil(sy, 1)
1560 sz = Utils.getNoNil(sz, 1)
1561
1562 animCurve:addKeyframe({x=x, y=y, z=z, rx=rx, ry=ry, rz=rz, sx=sx, sy=sy, sz=sz, time = keyTime})
1563 j = j + 1
1564 end
1565
1566 if j == 0 then
1567 local minY, maxY = StringUtil.getVectorFromString(getXMLString(xmlFile, nodeKey.."#minMaxY"))
1568 minY = Utils.getNoNil(minY, defaultY)
1569 maxY = Utils.getNoNil(maxY, defaultY)
1570 animCurve:addKeyframe({defaultX, minY, defaultZ, defaultRX, defaultRY, defaultRZ, 1, 1, 1, time = 0})
1571 animCurve:addKeyframe({defaultX, maxY, defaultZ, defaultRX, defaultRY, defaultRZ, 1, 1, 1, time = 1})
1572 end
1573
1574 local alwaysVisible = Utils.getNoNil(getXMLBool(xmlFile, nodeKey.."#alwaysVisible"), false)
1575 setVisibility(node, alwaysVisible)
1576
1577 table.insert(fillPlane.nodes, {node=node, animCurve=animCurve, alwaysVisible=alwaysVisible})
1578 end
1579 i = i + 1
1580 end
1581
1582 fillPlane.forcedFillType = nil
1583
1584 local defaultFillTypeStr = getXMLString(xmlFile, key .. "#defaultFillType")
1585 if defaultFillTypeStr ~= nil then
1586 local defaultFillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(defaultFillTypeStr)
1587 if defaultFillTypeIndex == nil then
1588 g_logManager:xmlWarning(self.configFileName, "Invalid defaultFillType '%s' for '%s'!", tostring(defaultFillTypeStr), key)
1589 return false
1590 else
1591 fillPlane.defaultFillType = defaultFillTypeIndex
1592 end
1593 else
1594 fillPlane.defaultFillType = next(fillUnit.supportedFillTypes)
1595 end
1596
1597 return true
1598end

loadFillUnitFromXML

Description
Definition
loadFillUnitFromXML()
Code
1249function FillUnit:loadFillUnitFromXML(xmlFile, key, entry, index)
1250 local spec = self.spec_fillUnit
1251
1252 entry.fillUnitIndex = index
1253 entry.capacity = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#capacity"), math.huge)
1254 entry.updateMass = Utils.getNoNil(getXMLBool(xmlFile, key .. "#updateMass"), true)
1255 entry.canBeUnloaded = Utils.getNoNil(getXMLBool(xmlFile, key .. "#canBeUnloaded"), true)
1256 entry.needsSaving = true
1257
1258 entry.fillLevel = 0
1259 entry.fillLevelSent = 0
1260
1261 entry.fillType = FillType.UNKNOWN
1262 entry.fillTypeSent = FillType.UNKNOWN
1263 entry.fillTypeToDisplay = FillType.UNKNOWN
1264 entry.fillLevelToDisplay = nil
1265
1266 entry.lastValidFillType = FillType.UNKNOWN
1267 entry.lastValidFillTypeSent = FillType.UNKNOWN
1268
1269 if hasXMLProperty(xmlFile, key .. ".exactFillRootNode") then
1270 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key .. ".exactFillRootNode#index", key .. ".exactFillRootNode#node") --FS17 to FS19
1271
1272 entry.exactFillRootNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. ".exactFillRootNode#node"), self.i3dMappings)
1273 if entry.exactFillRootNode ~= nil then
1274 local colMask = getCollisionMask(entry.exactFillRootNode)
1275 if bitAND(FillUnit.EXACTFILLROOTNODE_MASK, colMask) == 0 then
1276 g_logManager:xmlWarning(self.configFileName, "Invalid collision mask for exactFillRootNode '%s'. Bit 30 needs to be set!", key)
1277 return false
1278 end
1279
1280 spec.exactFillRootNodeToFillUnit[entry.exactFillRootNode] = entry
1281 spec.exactFillRootNodeToExtraDistance[entry.exactFillRootNode] = getXMLFloat(xmlFile, key .. ".exactFillRootNode#extraEffectDistance") or 0
1282 spec.hasExactFillRootNodes = true
1283 else
1284 g_logManager:xmlWarning(self.configFileName, "ExactFillRootNode not found for fillUnit '%s'!", key)
1285 end
1286 end
1287
1288 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key .. ".autoAimTargetNode#index", key .. ".autoAimTargetNode#node") --FS17 to FS19
1289
1290 entry.autoAimTarget = {}
1291 entry.autoAimTarget.node = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. ".autoAimTargetNode#node"), self.i3dMappings)
1292 if entry.autoAimTarget.node ~= nil then
1293 entry.autoAimTarget.baseTrans = {getTranslation(entry.autoAimTarget.node)}
1294 entry.autoAimTarget.startZ = getXMLFloat(xmlFile, key ..".autoAimTargetNode#startZ")
1295 entry.autoAimTarget.endZ = getXMLFloat(xmlFile, key ..".autoAimTargetNode#endZ")
1296 entry.autoAimTarget.startPercentage = Utils.getNoNil(getXMLFloat(xmlFile, key ..".autoAimTargetNode#startPercentage"), 25)/100
1297 entry.autoAimTarget.invert = Utils.getNoNil(getXMLBool(xmlFile, key ..".autoAimTargetNode#invert"), false)
1298 if entry.autoAimTarget.startZ ~= nil and entry.autoAimTarget.endZ ~= nil then
1299 local startZ = entry.autoAimTarget.startZ
1300 if entry.autoAimTarget.invert then
1301 startZ = entry.autoAimTarget.endZ
1302 end
1303
1304 setTranslation(entry.autoAimTarget.node, entry.autoAimTarget.baseTrans[1], entry.autoAimTarget.baseTrans[2], startZ)
1305 end
1306 end
1307
1308 entry.supportedFillTypes = {}
1309 local fillTypes
1310 local fillTypeCategories = getXMLString(xmlFile, key .. "#fillTypeCategories")
1311 local fillTypeNames = getXMLString(xmlFile, key .. "#fillTypes")
1312 if fillTypeCategories ~= nil and fillTypeNames == nil then
1313 fillTypes = g_fillTypeManager:getFillTypesByCategoryNames(fillTypeCategories, "Warning: '"..self.configFileName.. "' has invalid fillTypeCategory '%s'.")
1314 elseif fillTypeCategories == nil and fillTypeNames ~= nil then
1315 fillTypes = g_fillTypeManager:getFillTypesByNames(fillTypeNames, "Warning: '"..self.configFileName.. "' has invalid fillType '%s'.")
1316 else
1317 g_logManager:xmlWarning(self.configFileName, "Missing 'fillTypeCategories' or 'fillTypes' for fillUnit '%s'", key)
1318 return false
1319 end
1320
1321 if fillTypes ~= nil then
1322 for _,fillType in pairs(fillTypes) do
1323 entry.supportedFillTypes[fillType] = true
1324 end
1325 end
1326
1327 entry.supportedToolTypes = {}
1328 for i=1, g_toolTypeManager:getNumberOfToolTypes() do
1329 entry.supportedToolTypes[i] = true
1330 end
1331
1332 local startFillLevel = getXMLFloat(xmlFile, key .. "#startFillLevel")
1333 local startFillTypeStr = getXMLString(xmlFile, key .. "#startFillType")
1334 if startFillTypeStr ~= nil then
1335 local startFillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(startFillTypeStr)
1336 if startFillTypeIndex ~= nil then
1337 entry.startFillLevel = startFillLevel
1338 entry.startFillTypeIndex = startFillTypeIndex
1339 end
1340 end
1341
1342 entry.fillRootNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. ".fillRootNode#node"), self.i3dMappings)
1343 if entry.fillRootNode == nil then
1344 entry.fillRootNode = self.components[1].node
1345 end
1346
1347 entry.fillMassNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. ".fillMassNode#node"), self.i3dMappings)
1348 local updateFillLevelMass = Utils.getNoNil(getXMLBool(xmlFile, key .. "#updateFillLevelMass"), true)
1349 if entry.fillMassNode == nil and updateFillLevelMass then
1350 entry.fillMassNode = self.components[1].node
1351 end
1352
1353 -- mp sync info
1354 entry.synchronizeFillLevel = Utils.getNoNil(getXMLBool(xmlFile, key .. "#synchronizeFillLevel"), true)
1355 entry.synchronizeFullFillLevel = Utils.getNoNil(getXMLBool(xmlFile, key .. "#synchronizeFullFillLevel"), false)
1356
1357 local defaultBits = 16
1358 for startCapacity, bits in pairs(FillUnit.CAPACITY_TO_NETWORK_BITS) do
1359 if entry.capacity >= startCapacity then
1360 defaultBits = bits
1361 end
1362 end
1363
1364 entry.synchronizationNumBits = Utils.getNoNil(getXMLInt(xmlFile, key .. "#synchronizationNumBits"), defaultBits)
1365
1366 entry.showOnHud = Utils.getNoNil(getXMLBool(xmlFile, key .. "#showOnHud"), true)
1367 entry.blocksAutomatedTrainTravel = Utils.getNoNil(getXMLBool(xmlFile, key .. "#blocksAutomatedTrainTravel"), false)
1368
1369 entry.fillAnimation = getXMLString(xmlFile, key .. "#fillAnimation")
1370 entry.fillAnimationLoadTime = getXMLFloat(xmlFile, key .. "#fillAnimationLoadTime")
1371 entry.fillAnimationEmptyTime = getXMLFloat(xmlFile, key .. "#fillAnimationEmptyTime")
1372
1373 --
1374 if self.isClient then
1375 entry.alarmTriggers = {}
1376 local i = 0
1377 while true do
1378 local nodeKey = key .. string.format(".alarmTriggers.alarmTrigger(%d)", i)
1379 if not hasXMLProperty(xmlFile, nodeKey) then
1380 break
1381 end
1382 local alarmTrigger = {}
1383 if self:loadAlarmTrigger(xmlFile, nodeKey, alarmTrigger, entry) then
1384 table.insert(entry.alarmTriggers, alarmTrigger)
1385 end
1386 i = i + 1
1387 end
1388
1389 entry.measurementNodes = {}
1390 i = 0
1391 while true do
1392 local nodeKey = key .. string.format(".measurementNodes.measurementNode(%d)", i)
1393 if not hasXMLProperty(xmlFile, nodeKey) then
1394 break
1395 end
1396
1397 local measurementNode = {}
1398 if self:loadMeasurementNode(xmlFile, nodeKey, measurementNode) then
1399 table.insert(entry.measurementNodes, measurementNode)
1400 end
1401
1402 i = i + 1
1403 end
1404
1405 entry.fillPlane = {}
1406 entry.lastFillPlaneType = nil
1407 if not self:loadFillPlane(xmlFile, key..".fillPlane", entry.fillPlane, entry) then
1408 entry.fillPlane = nil
1409 end
1410
1411 entry.fillEffects = g_effectManager:loadEffect(xmlFile, key .. ".fillEffect", self.components, self, self.i3dMappings)
1412 entry.animationNodes = g_animationManager:loadAnimations(xmlFile, key..".animationNodes", self.components, self, self.i3dMappings)
1413
1414 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key .. ".fillLevelHud", key .. ".dashboard") --FS17 to FS19
1415
1416 if self.loadDashboardsFromXML ~= nil then
1417 self:loadDashboardsFromXML(xmlFile, key, {valueTypeToLoad = "fillLevel",
1418 valueObject = entry,
1419 valueFunc = "fillLevel",
1420 minFunc = 0,
1421 maxFunc = "capacity"})
1422
1423 self:loadDashboardsFromXML(xmlFile, key, {valueTypeToLoad = "fillLevelPct",
1424 valueObject = entry,
1425 valueFunc = function(fillUnit)
1426 return MathUtil.clamp(fillUnit.fillLevel/fillUnit.capacity, 0, 1) * 100
1427 end,
1428 minFunc = 0,
1429 maxFunc = 100})
1430
1431 self:loadDashboardsFromXML(xmlFile, key, {valueTypeToLoad = "fillLevelWarning",
1432 valueObject = entry,
1433 valueFunc = "fillLevel",
1434 minFunc = 0,
1435 maxFunc = "capacity",
1436 additionalAttributesFunc = Dashboard.warningAttributes,
1437 stateFunc = Dashboard.warningState})
1438 end
1439 end
1440
1441 return true
1442end

loadFillUnitUnloadingFromXML

Description
Definition
loadFillUnitUnloadingFromXML()
Code
955function FillUnit:loadFillUnitUnloadingFromXML(xmlFile, key, entry, index)
956 local spec = self.spec_fillUnit
957
958 entry.node = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key.."#node")) or self.rootNode
959 entry.width = getXMLFloat(self.xmlFile, key.."#width") or 15
960 entry.offset = StringUtil.getVectorNFromString(getXMLString(self.xmlFile, key.."#offset") or "0 0 0", 3)
961
962 return true
963end

loadMeasurementNode

Description
Definition
loadMeasurementNode()
Code
1470function FillUnit:loadMeasurementNode(xmlFile, key, entry)
1471 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key.."#index", key.."#node")
1472
1473 local node = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. "#node"), self.i3dMappings)
1474 if node == nil then
1475 g_logManager:xmlWarning(self.configFileName, "Missing 'node' for measurementNode '%s'", key)
1476 return false
1477 end
1478 entry.node = node
1479 entry.measurementTime = 0
1480
1481 return true
1482end

loadMovingToolFromXML

Description
Definition
loadMovingToolFromXML()
Code
1906function FillUnit:loadMovingToolFromXML(superFunc, xmlFile, key, entry)
1907 if not superFunc(self, xmlFile, key, entry) then
1908 return false
1909 end
1910
1911 entry.fillUnitIndex = getXMLInt(xmlFile, key .. "#fillUnitIndex")
1912 entry.minFillLevel = getXMLFloat(xmlFile, key .. "#minFillLevel")
1913 entry.maxFillLevel = getXMLFloat(xmlFile, key .. "#maxFillLevel")
1914
1915 return true
1916end

loadSpecValueCapacity

Description
Definition
loadSpecValueCapacity()
Code
1976function FillUnit.loadSpecValueCapacity(xmlFile, customEnvironment)
1977 local rootName = getXMLRootName(xmlFile)
1978
1979 local fillUnitConfigurations = {}
1980
1981 local overwrittenCapacity = getXMLFloat(xmlFile, rootName..".storeData.specs.capacity")
1982 local unit = getXMLString(xmlFile, rootName..".storeData.specs.capacity#unit")
1983 if overwrittenCapacity ~= nil and unit ~= nil then
1984 table.insert(fillUnitConfigurations, {{capacity=overwrittenCapacity, unit=unit}})
1985 return fillUnitConfigurations
1986 end
1987
1988 local i = 0
1989 while true do
1990 local key = string.format(rootName..".fillUnit.fillUnitConfigurations.fillUnitConfiguration(%d)", i)
1991 if not hasXMLProperty(xmlFile, key) then
1992 break
1993 end
1994
1995 local fillUnitConfiguration = {}
1996
1997 local j = 0
1998 while true do
1999 local fillUnitKey = string.format(key..".fillUnits.fillUnit(%d)", j)
2000 if not hasXMLProperty(xmlFile, fillUnitKey) then
2001 break
2002 end
2003
2004 local capacity = getXMLFloat(xmlFile, fillUnitKey .. "#capacity") or 0
2005 local unit = getXMLString(xmlFile, fillUnitKey .. "#unit")
2006
2007 if getXMLBool(xmlFile, fillUnitKey.."#showCapacityInShop") ~= false then
2008 if getXMLBool(xmlFile, fillUnitKey.."#showInShop") ~= false then
2009 table.insert(fillUnitConfiguration, {capacity=capacity, unit=unit})
2010 end
2011 end
2012
2013 j = j + 1
2014 end
2015
2016 table.insert(fillUnitConfigurations, fillUnitConfiguration)
2017
2018 i = i + 1
2019 end
2020
2021 return fillUnitConfigurations
2022end

loadSpecValueFillTypes

Description
Definition
loadSpecValueFillTypes()
Code
2081function FillUnit.loadSpecValueFillTypes(xmlFile, customEnvironment)
2082 local fillTypeNames = nil
2083 local fillTypeCategoryNames = nil
2084 local fillTypes = nil
2085 local fruitTypeNames = nil
2086
2087 local rootName = getXMLRootName(xmlFile)
2088
2089 -- get fill types of all configurations and all fill units to display all possible fill types
2090 local i = 0
2091 while true do
2092 local key = string.format(rootName..".fillUnit.fillUnitConfigurations.fillUnitConfiguration(%d)", i)
2093 if not hasXMLProperty(xmlFile, key) then
2094 break
2095 end
2096
2097 local j = 0
2098 while true do
2099 local unitKey = string.format(key..".fillUnits.fillUnit(%d)", j)
2100 if not hasXMLProperty(xmlFile, unitKey) then
2101 break
2102 end
2103
2104 local showInShop = getXMLBool(xmlFile, unitKey.."#showInShop")
2105 local capacity = getXMLFloat(xmlFile, unitKey.."#capacity")
2106 if (showInShop == nil or showInShop) and (capacity == nil or capacity > 0) then
2107 local currentFillTypes = getXMLString(xmlFile, unitKey .. "#fillTypes")
2108 if currentFillTypes ~= nil then
2109 if fillTypeNames == nil then
2110 fillTypeNames = currentFillTypes
2111 else
2112 fillTypeNames = fillTypeNames .. " " .. currentFillTypes
2113 end
2114 end
2115
2116 local currentFillTypeCategories = getXMLString(xmlFile, unitKey .. "#fillTypeCategories")
2117 if currentFillTypeCategories ~= nil then
2118 if fillTypeCategoryNames == nil then
2119 fillTypeCategoryNames = currentFillTypeCategories
2120 else
2121 fillTypeCategoryNames = fillTypeCategoryNames .. " " .. currentFillTypeCategories
2122 end
2123 end
2124 end
2125
2126 j = j + 1
2127 end
2128
2129 i = i + 1
2130 end
2131
2132 if fillTypeNames == nil then
2133 fillTypeNames = getXMLString(xmlFile, rootName..".fillTypes")
2134 end
2135
2136 fillTypeNames = Utils.getNoNil(getXMLString(xmlFile, rootName..".storeData.specs.fillTypes"), fillTypeNames)
2137 if fillTypeNames ~= nil then
2138 fillTypeCategoryNames = nil
2139 end
2140
2141 if fillTypeCategoryNames == nil then
2142 fillTypeCategoryNames = getXMLString(xmlFile, rootName..".fillTypeCategories")
2143 end
2144
2145 if fillTypes == nil then
2146 fruitTypeNames = getXMLString(xmlFile, rootName..".fruitTypes")
2147 end
2148
2149 if fillTypes == nil then
2150 fruitTypeNames = getXMLString(xmlFile, rootName..".cutter#fruitTypes")
2151 end
2152
2153 local fruitTypeCategoryNames = getXMLString(xmlFile, rootName..".cutter#fruitTypeCategories")
2154 local useWindrowed = Utils.getNoNil(getXMLBool(xmlFile, rootName..".cutter#useWindrowed"), false)
2155
2156 fillTypeCategoryNames = Utils.getNoNil(getXMLString(xmlFile, rootName..".storeData.specs.fillTypeCategories"), fillTypeCategoryNames)
2157
2158 return {categoryNames=fillTypeCategoryNames, fillTypeNames=fillTypeNames, fruitTypeNames=fruitTypeNames, fruitTypeCategoryNames=fruitTypeCategoryNames, useWindrowed=useWindrowed}
2159end

onDeactivate

Description
Definition
onDeactivate()
Code
543function FillUnit:onDeactivate()
544 local spec = self.spec_fillUnit
545 if spec.fillTrigger.isFilling then
546 self:setFillUnitIsFilling(false, true)
547 end
548end

onDelete

Description
Definition
onDelete()
Code
279function FillUnit:onDelete()
280 local spec = self.spec_fillUnit
281
282 g_currentMission:removeActivatableObject(spec.fillTrigger.activatable)
283 for _, trigger in pairs(spec.fillTrigger.triggers) do
284 trigger:onVehicleDeleted(self)
285 end
286
287 if spec.unloadTrigger ~= nil then
288 spec.unloadTrigger:delete()
289 end
290 if spec.loadTrigger ~= nil then
291 spec.loadTrigger:delete()
292 end
293end

onDraw

Description
Definition
onDraw()
Code
511function FillUnit:onDraw(isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
512 if self:getDrawFirstFillText() then
513 g_currentMission:addExtraPrintText(g_i18n:getText("info_firstFillTheTool"))
514 end
515
516 -- local spec = self.spec_fillUnit
517 -- if spec.unloading ~= nil then
518 -- for _, unloading in ipairs(spec.unloading) do
519 -- local node = unloading.node
520 -- DebugUtil.drawDebugNode(node, "n", false)
521 -- local ox, oy, oz = unpack(unloading.offset)
522 -- local x, y, z = localToWorld(node, ox - unloading.width*0.5, oy, oz)
523
524 -- local place = {}
525 -- place.startX, place.startY, place.startZ = x, y, z
526 -- place.rotX, place.rotY, place.rotZ = getWorldRotation(node)
527 -- place.dirX, place.dirY, place.dirZ = localDirectionToWorld(node, 1, 0, 0)
528 -- place.dirPerpX, place.dirPerpY, place.dirPerpZ = localDirectionToWorld(node, 0, 0, 1)
529 -- place.yOffset = 1
530 -- place.maxWidth = math.huge
531 -- place.maxLength = math.huge
532 -- place.width = unloading.width
533
534 -- drawDebugLine(place.startX, place.startY, place.startZ, 1, 0, 0, place.startX+place.dirX*place.width, place.startY+place.dirY*place.width, place.startZ+place.dirZ*place.width, 1, 0, 0)
535 -- DebugUtil.drawDebugGizmoAtWorldPos(place.startX, place.startY, place.startZ, place.dirX, place.dirY, place.dirZ, 0, 1, 0, "l")
536 -- DebugUtil.drawDebugGizmoAtWorldPos(place.startX+place.dirX*place.width, place.startY+place.dirY*place.width, place.startZ+place.dirZ*place.width, place.dirX, place.dirY, place.dirZ, 0, 1, 0, "r")
537 -- end
538 -- end
539end

onLoad

Description
Definition
onLoad()
Code
143function FillUnit:onLoad(savegame)
144 local spec = self.spec_fillUnit
145
146 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.measurementNodes.measurementNode", "vehicle.fillUnit.fillUnitConfigurations.fillUnitConfiguration.fillUnits.fillUnit.measurementNodes.measurementNode")
147 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.fillPlanes.fillPlane", "vehicle.fillUnit.fillUnitConfigurations.fillUnitConfiguration.fillUnits.fillUnit.fillPlane")
148 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.foldable.foldingParts#onlyFoldOnEmpty", "vehicle.fillUnit#allowFoldingWhileFilled")
149 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.fillAutoAimTargetNode", "vehicle.fillUnit.fillUnitConfigurations.fillUnitConfiguration.fillUnits.fillUnit.autoAimTargetNode") --FS17 to FS19
150
151
152 local fillUnitConfigurationId = Utils.getNoNil(self.configurations["fillUnit"], 1)
153 local baseKey = string.format("vehicle.fillUnit.fillUnitConfigurations.fillUnitConfiguration(%d).fillUnits", fillUnitConfigurationId -1)
154 ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.fillUnit.fillUnitConfigurations.fillUnitConfiguration", fillUnitConfigurationId , self.components, self)
155
156 spec.removeVehicleIfEmpty = Utils.getNoNil(getXMLBool(self.xmlFile, baseKey.."#removeVehicleIfEmpty"), false)
157 spec.allowFoldingWhileFilled = Utils.getNoNil(getXMLBool(self.xmlFile, baseKey.."#allowFoldingWhileFilled"), true)
158 spec.allowFoldingThreshold = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey.."#allowFoldingThreshold"), 0.0001)
159 spec.fillTypeChangeThreshold = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey.."#fillTypeChangeThreshold"), 0.05) -- fill level percentage that still allows overriding with another fill type
160 spec.fillUnits = {}
161 spec.exactFillRootNodeToFillUnit = {}
162 spec.exactFillRootNodeToExtraDistance = {}
163 spec.hasExactFillRootNodes = false
164 spec.activeAlarmTriggers = {}
165
166 spec.fillTrigger = {}
167 spec.fillTrigger.triggers = {}
168 spec.fillTrigger.activatable = FillActivatable:new(self)
169 spec.fillTrigger.isFilling = false
170 spec.fillTrigger.currentTrigger = nil
171 spec.fillTrigger.litersPerSecond = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey..".fillTrigger#litersPerSecond"), 50)
172 spec.fillTrigger.consumePtoPower = Utils.getNoNil(getXMLBool(self.xmlFile, baseKey..".fillTrigger#consumePtoPower"), false)
173
174 local i=0
175 while true do
176 local key = string.format("%s.fillUnit(%d)", baseKey, i)
177 if not hasXMLProperty(self.xmlFile, key) then
178 break
179 end
180 local entry = {}
181
182 if self:loadFillUnitFromXML(self.xmlFile, key, entry, i+1) then
183 table.insert(spec.fillUnits, entry)
184 else
185 g_logManager:xmlWarning(self.configFileName, "Could not load fillUnit for '%s'", key)
186 self:setLoadingState(BaseMission.VEHICLE_LOAD_ERROR)
187 break
188 end
189
190 i = i + 1
191 end
192
193 if hasXMLProperty(self.xmlFile, baseKey..".unloading") then
194 spec.unloading = {}
195 local i = 0
196 while true do
197 local unloadingKey = string.format("%s.unloading(%d)", baseKey, i)
198 if not hasXMLProperty(self.xmlFile, unloadingKey) then
199 break
200 end
201
202 local entry = {}
203
204 if self:loadFillUnitUnloadingFromXML(self.xmlFile, unloadingKey, entry, i+1) then
205 table.insert(spec.unloading, entry)
206 else
207 g_logManager:xmlWarning(self.configFileName, "Could not load unloading node for '%s'", unloadingKey)
208 break
209 end
210
211 i = i + 1
212 end
213 end
214
215 if self.isClient then
216 spec.samples = {}
217 spec.samples.fill = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.fillUnit.sounds", "fill", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self)
218
219 spec.fillEffects = g_effectManager:loadEffect(self.xmlFile, baseKey .. ".fillEffect", self.components, self, self.i3dMappings)
220 spec.animationNodes = g_animationManager:loadAnimations(self.xmlFile, baseKey..".animationNodes", self.components, self, self.i3dMappings)
221
222 spec.activeFillEffects = {}
223 spec.activeFillAnimations = {}
224 end
225
226 spec.dirtyFlag = self:getNextDirtyFlag()
227end

onPostLoad

Description
Definition
onPostLoad()
Code
231function FillUnit:onPostLoad(savegame)
232 local spec = self.spec_fillUnit
233
234 if self.isServer then
235 -- fill units that do not have a start fill level will be only loaded from savegame if not reseted and savegame available
236 local fillUnitsToLoad = {}
237 for i, fillUnit in ipairs(spec.fillUnits) do
238 if fillUnit.startFillLevel == nil and fillUnit.startFillTypeIndex == nil then
239 fillUnitsToLoad[i] = fillUnit
240 end
241 end
242
243 -- if the fill units are not in the savegame we fill them also with the start fill level (e.g. on a new savegame)
244 if savegame ~= nil and hasXMLProperty(savegame.xmlFile, savegame.key..".fillUnit") then
245 local i = 0
246 local xmlFile = savegame.xmlFile
247 while true do
248 local key = string.format("%s.fillUnit.unit(%d)", savegame.key, i)
249 if not hasXMLProperty(xmlFile, key) then
250 break
251 end
252
253 local fillUnitIndex = getXMLInt(xmlFile, key.."#index")
254
255 local allowLoading = fillUnitsToLoad[fillUnitIndex] == nil or -- always load (fill unit with start fill level)
256 (fillUnitsToLoad[fillUnitIndex] ~= nil and not savegame.resetVehicles) -- only load if not reseted (fill unit without start fill level)
257 if allowLoading then
258 local fillTypeName = getXMLString(xmlFile, key.."#fillType")
259 local fillLevel = getXMLFloat(xmlFile, key.."#fillLevel")
260 local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(fillTypeName)
261 self:addFillUnitFillLevel(self:getOwnerFarmId(), fillUnitIndex, fillLevel, fillTypeIndex, ToolType.UNDEFINED, nil)
262 end
263
264 i = i + 1
265 end
266 else
267 -- 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)
268 for fillUnitIndex, fillUnit in pairs(spec.fillUnits) do
269 if fillUnit.startFillLevel ~= nil and fillUnit.startFillTypeIndex ~= nil then
270 self:addFillUnitFillLevel(self:getOwnerFarmId(), fillUnitIndex, fillUnit.startFillLevel, fillUnit.startFillTypeIndex, ToolType.UNDEFINED, nil)
271 end
272 end
273 end
274 end
275end

onReadStream

Description
Definition
onReadStream()
Code
336function FillUnit:onReadStream(streamId, connection)
337 if connection:getIsServer() then
338 local spec = self.spec_fillUnit
339
340 self:setFillUnitIsFilling(streamReadBool(streamId), true)
341
342 if spec.loadTrigger ~= nil then
343 local loadTriggerId = streamReadInt32(streamId)
344 spec.loadTrigger:readStream(streamId, connection)
345 g_client:finishRegisterObject(self.loadTrigger, loadTriggerId)
346 end
347 if spec.unloadTrigger ~= nil then
348 local unloadTriggerId = streamReadInt32(streamId)
349 spec.unloadTrigger:readStream(streamId, connection)
350 g_client:finishRegisterObject(self.unloadTrigger, unloadTriggerId)
351 end
352 for i=1,table.getn(spec.fillUnits) do
353 if spec.fillUnits[i].synchronizeFillLevel then
354 local fillLevel = streamReadFloat32(streamId)
355 local fillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS)
356
357 self:addFillUnitFillLevel(self:getOwnerFarmId(), i, fillLevel, fillType, ToolType.UNDEFINED, nil)
358
359 local lastValidFillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS)
360 self:setFillUnitLastValidFillType(i, lastValidFillType, true)
361 end
362 end
363 end
364end

onReadUpdateStream

Description
Definition
onReadUpdateStream()
Code
397function FillUnit:onReadUpdateStream(streamId, timestamp, connection)
398 if connection:getIsServer() then
399 local spec = self.spec_fillUnit
400
401 if streamReadBool(streamId) then
402 for i=1,table.getn(spec.fillUnits) do
403 local fillUnit = spec.fillUnits[i]
404 if fillUnit.synchronizeFillLevel then
405 local fillLevel
406 if fillUnit.synchronizeFullFillLevel then
407 fillLevel = streamReadFloat32(streamId)
408 else
409 local maxValue = 2^fillUnit.synchronizationNumBits - 1
410 fillLevel = fillUnit.capacity * streamReadUIntN(streamId, fillUnit.synchronizationNumBits) / maxValue
411 end
412
413 local fillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS)
414 if fillLevel ~= fillUnit.fillLevel or fillType ~= fillUnit.fillType then
415 -- if fill type is unknown we empty the fillUnit
416 if fillType == FillType.UNKNOWN then
417 self:addFillUnitFillLevel(self:getOwnerFarmId(), i, -math.huge, self:getFillUnitFillType(i), ToolType.UNDEFINED, nil)
418 else
419 self:addFillUnitFillLevel(self:getOwnerFarmId(), i, fillLevel-fillUnit.fillLevel, fillType, ToolType.UNDEFINED, nil)
420 end
421 end
422
423 local lastValidFillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS)
424 self:setFillUnitLastValidFillType(i, lastValidFillType, lastValidFillType ~= fillUnit.lastValidFillType)
425 end
426 end
427 end
428 end
429end

onRegisterActionEvents

Description
Definition
onRegisterActionEvents()
Code
552function FillUnit:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
553 if self.isClient then
554 local spec = self.spec_fillUnit
555 self:clearActionEventsTable(spec.actionEvents)
556 if isActiveForInputIgnoreSelection then
557 if self.isServer and GS_IS_CONSOLE_VERSION and g_isDevelopmentVersion then
558 local _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.CONSOLE_DEBUG_FILLUNIT_NEXT, self, FillUnit.actionEventConsoleFillUnitNext, false, true, false, true, nil)
559 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
560 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_VERY_LOW)
561 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.CONSOLE_DEBUG_FILLUNIT_INC, self, FillUnit.actionEventConsoleFillUnitInc, false, true, false, true, nil)
562 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
563 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_VERY_LOW)
564 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.CONSOLE_DEBUG_FILLUNIT_DEC, self, FillUnit.actionEventConsoleFillUnitDec, false, true, false, true, nil)
565 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
566 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_VERY_LOW)
567 end
568
569 if spec.unloading ~= nil then
570 local _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.UNLOAD, self, FillUnit.actionEventUnload, false, true, false, true, nil)
571 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL)
572 spec.unloadActionEventId = actionEventId
573 FillUnit.updateUnloadActionDisplay(self)
574 end
575 end
576 end
577end

onUpdateTick

Description
Definition
onUpdateTick()
Code
462function FillUnit:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
463 local spec = self.spec_fillUnit
464
465 if self.isServer and spec.fillTrigger.isFilling then
466 local delta = 0
467 local trigger = spec.fillTrigger.currentTrigger
468 if trigger ~= nil then
469 delta = spec.fillTrigger.litersPerSecond*dt*0.001
470 delta = trigger:fillVehicle(self, delta, dt)
471 end
472
473 if delta <= 0 then
474 self:setFillUnitIsFilling(false)
475 end
476 end
477
478 if self.isClient then
479 for _, fillUnit in pairs(spec.fillUnits) do
480 self:updateMeasurementNodes(fillUnit, dt, false)
481 end
482
483 self:updateAlarmTriggers(spec.activeAlarmTriggers)
484
485 -- stop effects
486 for effect, time in pairs(spec.activeFillEffects) do
487 time = time - dt
488 if time < 0 then
489 g_effectManager:stopEffects(effect)
490 spec.activeFillEffects[effect] = nil
491 else
492 spec.activeFillEffects[effect] = time
493 end
494 end
495
496 -- stop animations
497 for animationNodes, time in pairs(spec.activeFillAnimations) do
498 time = time - dt
499 if time < 0 then
500 g_animationManager:stopAnimations(animationNodes)
501 spec.activeFillAnimations[animationNodes] = nil
502 else
503 spec.activeFillAnimations[animationNodes] = time
504 end
505 end
506 end
507end

onWriteStream

Description
Definition
onWriteStream()
Code
368function FillUnit:onWriteStream(streamId, connection)
369 if not connection:getIsServer() then
370 local spec = self.spec_fillUnit
371
372 streamWriteBool(streamId, spec.fillTrigger.isFilling)
373
374 if spec.loadTrigger ~= nil then
375 streamWriteInt32(streamId, NetworkUtil.getObjectId(spec.loadTrigger))
376 spec.loadTrigger:writeStream(streamId, connection)
377 g_server:registerObjectInStream(connection, spec.loadTrigger)
378 end
379 if spec.unloadTrigger ~= nil then
380 streamWriteInt32(streamId, NetworkUtil.getObjectId(spec.unloadTrigger))
381 spec.unloadTrigger:writeStream(streamId, connection)
382 g_server:registerObjectInStream(connection, spec.unloadTrigger)
383 end
384 for i=1,table.getn(spec.fillUnits) do
385 if spec.fillUnits[i].synchronizeFillLevel then
386 local fillUnit = spec.fillUnits[i]
387 streamWriteFloat32(streamId, fillUnit.fillLevel)
388 streamWriteUIntN(streamId, fillUnit.fillType, FillTypeManager.SEND_NUM_BITS)
389 streamWriteUIntN(streamId, fillUnit.lastValidFillType, FillTypeManager.SEND_NUM_BITS)
390 end
391 end
392 end
393end

onWriteUpdateStream

Description
Definition
onWriteUpdateStream()
Code
433function FillUnit:onWriteUpdateStream(streamId, connection, dirtyMask)
434 if not connection:getIsServer() then
435 local spec = self.spec_fillUnit
436
437 if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlag) ~= 0) then
438 for i=1,table.getn(spec.fillUnits) do
439 local fillUnit = spec.fillUnits[i]
440 if fillUnit.synchronizeFillLevel then
441 if fillUnit.synchronizeFullFillLevel then
442 streamWriteFloat32(streamId, fillUnit.fillLevelSent)
443 else
444 local percent = 0
445 if fillUnit.capacity > 0 then
446 percent = MathUtil.clamp(fillUnit.fillLevelSent / fillUnit.capacity, 0, 1)
447 end
448
449 local value = math.floor(percent * (2^fillUnit.synchronizationNumBits - 1) + 0.5)
450 streamWriteUIntN(streamId, value, fillUnit.synchronizationNumBits)
451 end
452 streamWriteUIntN(streamId, fillUnit.fillTypeSent, FillTypeManager.SEND_NUM_BITS)
453 streamWriteUIntN(streamId, fillUnit.lastValidFillTypeSent, FillTypeManager.SEND_NUM_BITS)
454 end
455 end
456 end
457 end
458end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
36function FillUnit.prerequisitesPresent(specializations)
37 return true
38end

registerEventListeners

Description
Definition
registerEventListeners()
Code
127function FillUnit.registerEventListeners(vehicleType)
128 SpecializationUtil.registerEventListener(vehicleType, "onLoad", FillUnit)
129 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", FillUnit)
130 SpecializationUtil.registerEventListener(vehicleType, "onDelete", FillUnit)
131 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", FillUnit)
132 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", FillUnit)
133 SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", FillUnit)
134 SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", FillUnit)
135 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", FillUnit)
136 SpecializationUtil.registerEventListener(vehicleType, "onDraw", FillUnit)
137 SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", FillUnit)
138 SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", FillUnit)
139end

registerEvents

Description
Definition
registerEvents()
Code
42function FillUnit.registerEvents(vehicleType)
43 SpecializationUtil.registerEvent(vehicleType, "onFillUnitFillLevelChanged")
44 SpecializationUtil.registerEvent(vehicleType, "onChangedFillType")
45 SpecializationUtil.registerEvent(vehicleType, "onAlarmTriggerChanged")
46 SpecializationUtil.registerEvent(vehicleType, "onAddedFillUnitTrigger")
47 SpecializationUtil.registerEvent(vehicleType, "onRemovedFillUnitTrigger")
48 SpecializationUtil.registerEvent(vehicleType, "onFillUnitIsFillingStateChanged")
49end

registerFunctions

Description
Definition
registerFunctions()
Code
53function FillUnit.registerFunctions(vehicleType)
54 SpecializationUtil.registerFunction(vehicleType, "getDrawFirstFillText", FillUnit.getDrawFirstFillText)
55 SpecializationUtil.registerFunction(vehicleType, "getFillUnits", FillUnit.getFillUnits)
56 SpecializationUtil.registerFunction(vehicleType, "getFillUnitByIndex", FillUnit.getFillUnitByIndex)
57 SpecializationUtil.registerFunction(vehicleType, "getFillUnitExists", FillUnit.getFillUnitExists)
58 SpecializationUtil.registerFunction(vehicleType, "getFillUnitCapacity", FillUnit.getFillUnitCapacity)
59 SpecializationUtil.registerFunction(vehicleType, "getFillUnitFreeCapacity", FillUnit.getFillUnitFreeCapacity)
60 SpecializationUtil.registerFunction(vehicleType, "getFillUnitFillLevel", FillUnit.getFillUnitFillLevel)
61 SpecializationUtil.registerFunction(vehicleType, "getFillUnitFillLevelPercentage", FillUnit.getFillUnitFillLevelPercentage)
62 SpecializationUtil.registerFunction(vehicleType, "getFillUnitFillType", FillUnit.getFillUnitFillType)
63 SpecializationUtil.registerFunction(vehicleType, "getFillUnitLastValidFillType", FillUnit.getFillUnitLastValidFillType)
64 SpecializationUtil.registerFunction(vehicleType, "getFillUnitFirstSupportedFillType", FillUnit.getFillUnitFirstSupportedFillType)
65 SpecializationUtil.registerFunction(vehicleType, "getFillUnitExactFillRootNode", FillUnit.getFillUnitExactFillRootNode)
66 SpecializationUtil.registerFunction(vehicleType, "getFillUnitRootNode", FillUnit.getFillUnitRootNode)
67 SpecializationUtil.registerFunction(vehicleType, "getFillUnitAutoAimTargetNode", FillUnit.getFillUnitAutoAimTargetNode)
68 SpecializationUtil.registerFunction(vehicleType, "getFillUnitSupportsFillType", FillUnit.getFillUnitSupportsFillType)
69 SpecializationUtil.registerFunction(vehicleType, "getFillUnitSupportsToolType", FillUnit.getFillUnitSupportsToolType)
70 SpecializationUtil.registerFunction(vehicleType, "getFillUnitSupportsToolTypeAndFillType", FillUnit.getFillUnitSupportsToolTypeAndFillType)
71 SpecializationUtil.registerFunction(vehicleType, "getFillUnitSupportedFillTypes", FillUnit.getFillUnitSupportedFillTypes)
72 SpecializationUtil.registerFunction(vehicleType, "getFillUnitSupportedToolTypes", FillUnit.getFillUnitSupportedToolTypes)
73 SpecializationUtil.registerFunction(vehicleType, "getFillUnitAllowsFillType", FillUnit.getFillUnitAllowsFillType)
74 SpecializationUtil.registerFunction(vehicleType, "getFillTypeChangeThreshold", FillUnit.getFillTypeChangeThreshold)
75 SpecializationUtil.registerFunction(vehicleType, "getFirstValidFillUnitToFill", FillUnit.getFirstValidFillUnitToFill)
76 SpecializationUtil.registerFunction(vehicleType, "setFillUnitFillType", FillUnit.setFillUnitFillType)
77 SpecializationUtil.registerFunction(vehicleType, "setFillUnitFillTypeToDisplay", FillUnit.setFillUnitFillTypeToDisplay)
78 SpecializationUtil.registerFunction(vehicleType, "setFillUnitFillLevelToDisplay", FillUnit.setFillUnitFillLevelToDisplay)
79 SpecializationUtil.registerFunction(vehicleType, "setFillUnitCapacity", FillUnit.setFillUnitCapacity)
80 SpecializationUtil.registerFunction(vehicleType, "setFillUnitForcedMaterialFillType", FillUnit.setFillUnitForcedMaterialFillType)
81 SpecializationUtil.registerFunction(vehicleType, "getFillUnitForcedMaterialFillType", FillUnit.getFillUnitForcedMaterialFillType)
82 SpecializationUtil.registerFunction(vehicleType, "updateAlarmTriggers", FillUnit.updateAlarmTriggers)
83 SpecializationUtil.registerFunction(vehicleType, "getAlarmTriggerIsActive", FillUnit.getAlarmTriggerIsActive)
84 SpecializationUtil.registerFunction(vehicleType, "setAlarmTriggerState", FillUnit.setAlarmTriggerState)
85 SpecializationUtil.registerFunction(vehicleType, "getFillUnitIndexFromNode", FillUnit.getFillUnitIndexFromNode)
86 SpecializationUtil.registerFunction(vehicleType, "getFillUnitExtraDistanceFromNode", FillUnit.getFillUnitExtraDistanceFromNode)
87 SpecializationUtil.registerFunction(vehicleType, "getFillUnitFromNode", FillUnit.getFillUnitFromNode)
88 SpecializationUtil.registerFunction(vehicleType, "addFillUnitFillLevel", FillUnit.addFillUnitFillLevel)
89 SpecializationUtil.registerFunction(vehicleType, "setFillUnitLastValidFillType", FillUnit.setFillUnitLastValidFillType)
90 SpecializationUtil.registerFunction(vehicleType, "loadFillUnitFromXML", FillUnit.loadFillUnitFromXML)
91 SpecializationUtil.registerFunction(vehicleType, "loadAlarmTrigger", FillUnit.loadAlarmTrigger)
92 SpecializationUtil.registerFunction(vehicleType, "loadMeasurementNode", FillUnit.loadMeasurementNode)
93 SpecializationUtil.registerFunction(vehicleType, "updateMeasurementNodes", FillUnit.updateMeasurementNodes)
94 SpecializationUtil.registerFunction(vehicleType, "loadFillPlane", FillUnit.loadFillPlane)
95 SpecializationUtil.registerFunction(vehicleType, "setFillPlaneForcedFillType", FillUnit.setFillPlaneForcedFillType)
96 SpecializationUtil.registerFunction(vehicleType, "updateFillUnitFillPlane", FillUnit.updateFillUnitFillPlane)
97 SpecializationUtil.registerFunction(vehicleType, "updateFillUnitAutoAimTarget", FillUnit.updateFillUnitAutoAimTarget)
98 SpecializationUtil.registerFunction(vehicleType, "addFillUnitTrigger", FillUnit.addFillUnitTrigger)
99 SpecializationUtil.registerFunction(vehicleType, "removeFillUnitTrigger", FillUnit.removeFillUnitTrigger)
100 SpecializationUtil.registerFunction(vehicleType, "setFillUnitIsFilling", FillUnit.setFillUnitIsFilling)
101 SpecializationUtil.registerFunction(vehicleType, "setFillSoundIsPlaying", FillUnit.setFillSoundIsPlaying)
102 SpecializationUtil.registerFunction(vehicleType, "getIsFillUnitActive", FillUnit.getIsFillUnitActive)
103 SpecializationUtil.registerFunction(vehicleType, "updateFillUnitTriggers", FillUnit.updateFillUnitTriggers)
104 SpecializationUtil.registerFunction(vehicleType, "emptyAllFillUnits", FillUnit.emptyAllFillUnits)
105 SpecializationUtil.registerFunction(vehicleType, "unloadFillUnits", FillUnit.unloadFillUnits)
106 SpecializationUtil.registerFunction(vehicleType, "loadFillUnitUnloadingFromXML", FillUnit.loadFillUnitUnloadingFromXML)
107end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
112function FillUnit.registerOverwrittenFunctions(vehicleType)
113 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAdditionalComponentMass", FillUnit.getAdditionalComponentMass)
114 SpecializationUtil.registerOverwrittenFunction(vehicleType, "addNodeObjectMapping", FillUnit.addNodeObjectMapping)
115 SpecializationUtil.registerOverwrittenFunction(vehicleType, "removeNodeObjectMapping", FillUnit.removeNodeObjectMapping)
116 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getFillLevelInformation", FillUnit.getFillLevelInformation)
117 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsFoldAllowed", FillUnit.getIsFoldAllowed)
118 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsReadyForAutomatedTrainTravel", FillUnit.getIsReadyForAutomatedTrainTravel)
119 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadMovingToolFromXML", FillUnit.loadMovingToolFromXML)
120 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsMovingToolActive", FillUnit.getIsMovingToolActive)
121 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDoConsumePtoPower", FillUnit.getDoConsumePtoPower)
122 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsPowerTakeOffActive", FillUnit.getIsPowerTakeOffActive)
123end

removeFillUnitTrigger

Description
Removes fill trigger
Definition
removeFillUnitTrigger(table trigger)
Arguments
tabletriggertrigger
Code
1686function FillUnit:removeFillUnitTrigger(trigger)
1687 local spec = self.spec_fillUnit
1688 ListUtil.removeElementFromList(spec.fillTrigger.triggers, trigger)
1689
1690 if self.isServer and trigger == spec.fillTrigger.currentTrigger then
1691 self:setFillUnitIsFilling(false)
1692 end
1693
1694 if #spec.fillTrigger.triggers == 0 then
1695 g_currentMission:removeActivatableObject(spec.fillTrigger.activatable)
1696 end
1697
1698 SpecializationUtil.raiseEvent(self, "onRemovedFillUnitTrigger", #spec.fillTrigger.triggers)
1699end

removeNodeObjectMapping

Description
Definition
removeNodeObjectMapping()
Code
1826function FillUnit:removeNodeObjectMapping(superFunc, list)
1827 superFunc(self, list)
1828
1829 local spec = self.spec_fillUnit
1830
1831 for _,fillUnit in pairs(spec.fillUnits) do
1832 if fillUnit.fillRootNode ~= nil then
1833 list[fillUnit.fillRootNode] = nil
1834 end
1835 if fillUnit.exactFillRootNode ~= nil then
1836 list[fillUnit.exactFillRootNode] = nil
1837 end
1838 end
1839end

saveStatsToXMLFile

Description
Definition
saveStatsToXMLFile()
Code
314function FillUnit:saveStatsToXMLFile(xmlFile, key)
315 local spec = self.spec_fillUnit
316
317 local fillTypes = ''
318 local fillLevels = ''
319 local numFillUnits = table.getn(spec.fillUnits)
320 for i,fillUnit in ipairs(spec.fillUnits) do
321 local fillTypeName = Utils.getNoNil(g_fillTypeManager:getFillTypeNameByIndex(fillUnit.fillType), "unknown")
322 fillTypes = fillTypes .. HTMLUtil.encodeToHTML(tostring(fillTypeName))
323 fillLevels = fillLevels .. string.format("%.3f", fillUnit.fillLevel)
324 if numFillUnits > 1 and i ~= numFillUnits then
325 fillTypes = fillTypes .. ' '
326 fillLevels = fillLevels .. ' '
327 end
328 end
329
330 setXMLString(xmlFile, key.."#fillTypes", fillTypes)
331 setXMLString(xmlFile, key.."#fillLevels", fillLevels)
332end

saveToXMLFile

Description
Definition
saveToXMLFile()
Code
297function FillUnit:saveToXMLFile(xmlFile, key, usedModNames)
298 local spec = self.spec_fillUnit
299 local i = 0
300 for k, fillUnit in ipairs(spec.fillUnits) do
301 if fillUnit.needsSaving then
302 local fillUnitKey = string.format("%s.unit(%d)", key, i)
303 local fillTypeName = Utils.getNoNil(g_fillTypeManager:getFillTypeNameByIndex(fillUnit.fillType), "unknown")
304 setXMLInt(xmlFile, fillUnitKey.."#index", k)
305 setXMLString(xmlFile, fillUnitKey.."#fillType", fillTypeName)
306 setXMLFloat(xmlFile, fillUnitKey.."#fillLevel", fillUnit.fillLevel)
307 i = i + 1
308 end
309 end
310end

setAlarmTriggerState

Description
Definition
setAlarmTriggerState()
Code
888function FillUnit:setAlarmTriggerState(alarmTrigger, state)
889 local spec = self.spec_fillUnit
890
891 if state ~= alarmTrigger.isActive then
892 if state then
893 if alarmTrigger.sample ~= nil then
894 g_soundManager:playSample(alarmTrigger.sample)
895 end
896 spec.activeAlarmTriggers[alarmTrigger] = alarmTrigger
897 else
898 if alarmTrigger.sample ~= nil then
899 g_soundManager:stopSample(alarmTrigger.sample)
900 end
901 spec.activeAlarmTriggers[alarmTrigger] = nil
902 end
903
904 alarmTrigger.isActive = state
905 end
906
907 SpecializationUtil.raiseEvent(self, "onAlarmTriggerChanged", alarmTrigger, state)
908end

setFillPlaneForcedFillType

Description
Definition
setFillPlaneForcedFillType()
Code
1602function FillUnit:setFillPlaneForcedFillType(fillUnitIndex, forcedFillType)
1603 local spec = self.spec_fillUnit
1604 if spec.fillUnits[fillUnitIndex] ~= nil then
1605 if spec.fillUnits[fillUnitIndex].fillPlane ~= nil then
1606 spec.fillUnits[fillUnitIndex].fillPlane.forcedFillType = forcedFillType
1607 end
1608 end
1609end

setFillSoundIsPlaying

Description
Definition
setFillSoundIsPlaying()
Code
1769function FillUnit:setFillSoundIsPlaying(isPlaying)
1770 local spec = self.spec_fillUnit
1771 if isPlaying then
1772 if not g_soundManager:getIsSamplePlaying(spec.samples.fill) then
1773 g_soundManager:playSample(spec.samples.fill)
1774 end
1775 else
1776 if g_soundManager:getIsSamplePlaying(spec.samples.fill) then
1777 g_soundManager:stopSample(spec.samples.fill)
1778 end
1779 end
1780end

setFillUnitCapacity

Description
Definition
setFillUnitCapacity()
Code
832function FillUnit:setFillUnitCapacity(fillUnitIndex, capacity)
833 local spec = self.spec_fillUnit
834 if spec.fillUnits[fillUnitIndex] ~= nil then
835 spec.fillUnits[fillUnitIndex].capacity = capacity
836 end
837end

setFillUnitFillLevelToDisplay

Description
Definition
setFillUnitFillLevelToDisplay()
Code
822function FillUnit:setFillUnitFillLevelToDisplay(fillUnitIndex, fillLevel, isPersistent)
823 local spec = self.spec_fillUnit
824 if spec.fillUnits[fillUnitIndex] ~= nil then
825 spec.fillUnits[fillUnitIndex].fillLevelToDisplay = fillLevel
826 spec.fillUnits[fillUnitIndex].fillLevelToDisplayIsPersistent = isPersistent ~= nil and isPersistent
827 end
828end

setFillUnitFillType

Description
Definition
setFillUnitFillType()
Code
801function FillUnit:setFillUnitFillType(fillUnitIndex, fillTypeIndex)
802 local spec = self.spec_fillUnit
803 local oldFillTypeIndex = spec.fillUnits[fillUnitIndex].fillType
804 if oldFillTypeIndex ~= fillTypeIndex then
805 spec.fillUnits[fillUnitIndex].fillType = fillTypeIndex
806 SpecializationUtil.raiseEvent(self, "onChangedFillType", fillUnitIndex, fillTypeIndex, oldFillTypeIndex)
807 end
808end

setFillUnitFillTypeToDisplay

Description
Definition
setFillUnitFillTypeToDisplay()
Code
812function FillUnit:setFillUnitFillTypeToDisplay(fillUnitIndex, fillTypeIndex, isPersistent)
813 local spec = self.spec_fillUnit
814 if spec.fillUnits[fillUnitIndex] ~= nil then
815 spec.fillUnits[fillUnitIndex].fillTypeToDisplay = fillTypeIndex
816 spec.fillUnits[fillUnitIndex].fillTypeToDisplayIsPersistent = isPersistent ~= nil and isPersistent
817 end
818end

setFillUnitForcedMaterialFillType

Description
Definition
setFillUnitForcedMaterialFillType()
Code
841function FillUnit:setFillUnitForcedMaterialFillType(fillUnitIndex, forcedMaterialFillType)
842 local spec = self.spec_fillUnit
843 if spec.fillUnits[fillUnitIndex] ~= nil then
844 spec.fillUnits[fillUnitIndex].forcedMaterialFillType = forcedMaterialFillType
845 end
846
847 self:setFillPlaneForcedFillType(fillUnitIndex, forcedMaterialFillType)
848
849 if self.setFillVolumeForcedFillTypeByFillUnitIndex ~= nil then
850 self:setFillVolumeForcedFillTypeByFillUnitIndex(fillUnitIndex, forcedMaterialFillType)
851 end
852end

setFillUnitIsFilling

Description
Definition
setFillUnitIsFilling()
Code
1729function FillUnit:setFillUnitIsFilling(isFilling, noEventSend)
1730 local spec = self.spec_fillUnit
1731 if isFilling ~= spec.fillTrigger.isFilling then
1732 if noEventSend == nil or noEventSend == false then
1733 if g_server ~= nil then
1734 g_server:broadcastEvent(SetFillUnitIsFillingEvent:new(self, isFilling), nil, nil, self)
1735 else
1736 g_client:getServerConnection():sendEvent(SetFillUnitIsFillingEvent:new(self, isFilling))
1737 end
1738 end
1739
1740 spec.fillTrigger.isFilling = isFilling
1741 if isFilling then
1742 -- find the first trigger which is activable
1743 spec.fillTrigger.currentTrigger = nil
1744 for _, trigger in ipairs(spec.fillTrigger.triggers) do
1745 if trigger:getIsActivatable(self) then
1746 spec.fillTrigger.currentTrigger = trigger
1747 break
1748 end
1749 end
1750 end
1751 if self.isClient then
1752 self:setFillSoundIsPlaying(isFilling)
1753
1754 if spec.fillTrigger.currentTrigger ~= nil then
1755 spec.fillTrigger.currentTrigger:setFillSoundIsPlaying(isFilling)
1756 end
1757 end
1758
1759 SpecializationUtil.raiseEvent(self, "onFillUnitIsFillingStateChanged", isFilling)
1760
1761 if not isFilling then
1762 self:updateFillUnitTriggers()
1763 end
1764 end
1765end

setFillUnitLastValidFillType

Description
Definition
setFillUnitLastValidFillType()
Code
1237function FillUnit:setFillUnitLastValidFillType(fillUnitIndex, fillType, force)
1238 local spec = self.spec_fillUnit
1239 local fillUnit = spec.fillUnits[fillUnitIndex]
1240 if fillUnit ~= nil and fillUnit.lastValidFillType ~= fillType then
1241 fillUnit.lastValidFillType = fillType
1242 fillUnit.lastValidFillTypeSent = fillType
1243 self:raiseDirtyFlags(spec.dirtyFlag)
1244 end
1245end

unloadFillUnits

Description
Definition
unloadFillUnits()
Code
967function FillUnit:unloadFillUnits(ignoreWarning)
968 if not self.isServer then
969 g_client:getServerConnection():sendEvent(FillUnitUnloadEvent:new(self))
970
971 else
972 local spec = self.spec_fillUnit
973 local unloadingPlaces = spec.unloading
974
975 local places = {}
976
977 for _, unloading in ipairs(unloadingPlaces) do
978 local node = unloading.node
979 local ox, oy, oz = unpack(unloading.offset)
980 local x, y, z = localToWorld(node, ox - unloading.width*0.5, oy, oz)
981
982 local place = {}
983 place.startX, place.startY, place.startZ = x, y, z
984 place.rotX, place.rotY, place.rotZ = getWorldRotation(node)
985 place.dirX, place.dirY, place.dirZ = localDirectionToWorld(node, 1, 0, 0)
986 place.dirPerpX, place.dirPerpY, place.dirPerpZ = localDirectionToWorld(node, 0, 0, 1)
987 place.yOffset = 1
988 place.maxWidth = math.huge
989 place.maxLength = math.huge
990 place.width = unloading.width
991
992 table.insert(places, place)
993 end
994
995 local usedPlaces = {}
996 local success = true
997
998 local availablePallets = {}
999
1000 for k, fillUnit in ipairs(self:getFillUnits()) do
1001 local fillLevel = self:getFillUnitFillLevel(k)
1002 local fillTypeIndex = self:getFillUnitFillType(k)
1003 local fillType = g_fillTypeManager:getFillTypeByIndex(fillTypeIndex)
1004 if fillUnit.canBeUnloaded and fillLevel > 0 and fillType.palletFilename ~= nil then
1005 while fillLevel > 0 do
1006 local pallet = availablePallets[fillTypeIndex]
1007 local isNewPallet = false
1008 if pallet == nil then
1009 local sizeWidth, sizeLength, widthOffset, lengthOffset = StoreItemUtil.getSizeValues(fillType.palletFilename, "vehicle", 0, {})
1010 local x, _, z, place, width, _ = PlacementUtil.getPlace(places, sizeWidth, sizeLength, widthOffset, lengthOffset, usedPlaces, true, true, true)
1011
1012 if x == nil then
1013 success = false
1014 break
1015 end
1016
1017 PlacementUtil.markPlaceUsed(usedPlaces, place, width)
1018 pallet = g_currentMission:loadVehicle(fillType.palletFilename, x, nil, z, 0, place.rotY, true, 0, Vehicle.PROPERTY_STATE_OWNED, self:getOwnerFarmId(), nil, nil)
1019 pallet:emptyAllFillUnits(true)
1020 isNewPallet = true
1021 end
1022
1023 local fillUnitIndex = pallet:getFirstValidFillUnitToFill(fillTypeIndex)
1024 if fillUnitIndex ~= nil then
1025 local appliedDelta = pallet:addFillUnitFillLevel(self:getOwnerFarmId(), fillUnitIndex, fillLevel, fillTypeIndex, ToolType.UNDEFINED, nil)
1026 self:addFillUnitFillLevel(self:getOwnerFarmId(), k, -appliedDelta, fillTypeIndex, ToolType.UNDEFINED, nil)
1027 fillLevel = fillLevel - appliedDelta
1028 else
1029 if isNewPallet then
1030 break
1031 end
1032 availablePallets[fillTypeIndex] = nil
1033 end
1034 end
1035 end
1036 end
1037
1038 if ignoreWarning == nil or not ignoreWarning then
1039 if not success then
1040 g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_INFO, g_i18n:getText("fillUnit_unload_nospace"))
1041 end
1042 end
1043
1044 return success
1045 end
1046end

updateAlarmTriggers

Description
Definition
updateAlarmTriggers()
Code
867function FillUnit:updateAlarmTriggers(alarmTriggers)
868 for _, alarmTrigger in pairs(alarmTriggers) do
869 self:setAlarmTriggerState(alarmTrigger, self:getAlarmTriggerIsActive(alarmTrigger))
870 end
871end

updateFillUnitAutoAimTarget

Description
Definition
updateFillUnitAutoAimTarget()
Code
1654function FillUnit:updateFillUnitAutoAimTarget(fillUnit)
1655 local autoAimTarget = fillUnit.autoAimTarget
1656 if autoAimTarget.node ~= nil then
1657 if autoAimTarget.startZ ~= nil and autoAimTarget.endZ ~= nil then
1658 local startFillLevel = fillUnit.capacity * autoAimTarget.startPercentage
1659 local percent = MathUtil.clamp((fillUnit.fillLevel-startFillLevel) / (fillUnit.capacity-startFillLevel), 0, 1)
1660 if autoAimTarget.invert then
1661 percent = 1 - percent
1662 end
1663 local newZ = (autoAimTarget.endZ-autoAimTarget.startZ) * percent + autoAimTarget.startZ
1664 setTranslation(autoAimTarget.node, autoAimTarget.baseTrans[1], autoAimTarget.baseTrans[2], newZ)
1665 end
1666 end
1667end

updateFillUnitFillPlane

Description
Definition
updateFillUnitFillPlane()
Code
1613function FillUnit:updateFillUnitFillPlane(fillUnit)
1614 local fillPlane = fillUnit.fillPlane
1615 if fillPlane ~= nil then
1616 local t = self:getFillUnitFillLevelPercentage(fillUnit.fillUnitIndex)
1617
1618 for _, node in ipairs(fillPlane.nodes) do
1619 local x,y,z, rx,ry,rz, sx,sy,sz = node.animCurve:get(t)
1620
1621 setTranslation(node.node, x, y, z)
1622 setRotation(node.node, rx, ry, rz)
1623 setScale(node.node, sx, sy, sz)
1624 setVisibility(node.node, fillUnit.fillLevel > 0 or node.alwaysVisible)
1625 end
1626
1627 --assign new material on fill type change
1628 if fillUnit.fillType ~= fillUnit.lastFillPlaneType then
1629 if fillUnit.fillType ~= FillType.UNKNOWN then
1630 local usedFillType = fillUnit.fillType
1631 if fillPlane.forcedFillType ~= nil then
1632 usedFillType = fillPlane.forcedFillType
1633 end
1634
1635 local material = g_materialManager:getMaterial(usedFillType, "fillplane", 1)
1636 if material == nil and fillPlane.defaultFillType ~= nil then
1637 material = g_materialManager:getMaterial(fillPlane.defaultFillType, "fillplane", 1)
1638 end
1639
1640 if material ~= nil then
1641 for _, node in ipairs(fillPlane.nodes) do
1642 setMaterial(node.node, material, 0)
1643 end
1644 end
1645 end
1646
1647 fillUnit.lastFillPlaneType = fillUnit.fillType
1648 end
1649 end
1650end

updateFillUnitTriggers

Description
Definition
updateFillUnitTriggers()
Code
1703function FillUnit:updateFillUnitTriggers()
1704 local spec = self.spec_fillUnit
1705 table.sort(spec.fillTrigger.triggers, function(t1, t2)
1706 local fillTypeIndex1 = t1:getCurrentFillType()
1707 local fillTypeIndex2 = t2:getCurrentFillType()
1708
1709 local t1FillUnitIndex = self:getFirstValidFillUnitToFill(fillTypeIndex1)
1710 local t2FillUnitIndex = self:getFirstValidFillUnitToFill(fillTypeIndex2)
1711
1712 if t1FillUnitIndex ~= nil and t2FillUnitIndex ~= nil then
1713 return self:getFillUnitFillLevel(t1FillUnitIndex) > self:getFillUnitFillLevel(t2FillUnitIndex)
1714 elseif t1FillUnitIndex ~= nil then
1715 return true
1716 end
1717
1718 return false
1719 end)
1720
1721 if #spec.fillTrigger.triggers > 0 then
1722 local fillTypeIndex = spec.fillTrigger.triggers[1]:getCurrentFillType()
1723 spec.fillTrigger.activatable:setFillType(fillTypeIndex)
1724 end
1725end

updateMeasurementNodes

Description
Definition
updateMeasurementNodes()
Code
1486function FillUnit:updateMeasurementNodes(fillUnit, dt, setActive)
1487 if fillUnit.measurementNodes ~= nil then
1488 for _, measurementNode in pairs(fillUnit.measurementNodes) do
1489 if setActive ~= nil and setActive then
1490 measurementNode.measurementTime = 5000
1491 end
1492
1493 if measurementNode.measurementTime > 0 then
1494 measurementNode.measurementTime = math.max(measurementNode.measurementTime - dt, 0)
1495
1496 local isWorking = math.min(measurementNode.measurementTime / 1000, 1)
1497 if measurementNode.measurementTime == 0 or fillUnit.fillLevel <= 0 then
1498 isWorking = 0
1499 end
1500
1501 setShaderParameter(measurementNode.node, "fillLevel", fillUnit.fillLevel / fillUnit.capacity, isWorking, 0, 0, false)
1502 end
1503 end
1504 end
1505end

updateUnloadActionDisplay

Description
Definition
updateUnloadActionDisplay()
Code
2248function FillUnit.updateUnloadActionDisplay(self)
2249 local spec = self.spec_fillUnit
2250 if spec.unloading ~= nil then
2251 local isActive = false
2252 for k, fillUnit in ipairs(self:getFillUnits()) do
2253 local fillLevel = self:getFillUnitFillLevel(k)
2254 local fillTypeIndex = self:getFillUnitFillType(k)
2255 local fillType = g_fillTypeManager:getFillTypeByIndex(fillTypeIndex)
2256 if fillUnit.canBeUnloaded and fillLevel > 0 and fillType.palletFilename ~= nil then
2257 isActive = true
2258 break
2259 end
2260 end
2261
2262 g_inputBinding:setActionEventActive(spec.unloadActionEventId, isActive)
2263 end
2264end