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
- AIConveyorBelt
- AIDrivable
- AIFieldWorker
- AIImplement
- AIJobVehicle
- AIVehicle
- AIVehicleObstacle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- AutoLoader
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BaseMaterial
- BigBag
- BunkerSiloCompacter
- BunkerSiloInteractor
- CCTDrivable
- Combine
- ConnectionHoses
- ConveyorBelt
- Cover
- CrabSteering
- Crawlers
- CropSensor
- Cultivator
- Cutter
- Cylindered
- CylinderedFoldable
- Dashboard
- Dischargeable
- Drivable
- DynamicallyLoadedParts
- DynamicMountAttacher
- Enterable
- ExtendedAIVehicle
- ExtendedCombine
- ExtendedMotorized
- ExtendedMower
- ExtendedSowingMachine
- ExtendedSprayer
- ExtendedWearable
- FertilizingCultivator
- FertilizingSowingMachine
- FillTriggerVehicle
- FillUnit
- FillVolume
- Foldable
- FoliageBending
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- GroundAdjustedNodes
- GroundReference
- HeadlandAnimation
- Honk
- HookLiftContainer
- HookLiftTrailer
- IKChains
- InlineWrapper
- JigglingParts
- Leveler
- LicensePlates
- Lights
- LivestockTrailer
- Locomotive
- LogGrab
- ManureBarrel
- ManureSensor
- MixerWagon
- Motorized
- Mountable
- Mower
- Mulcher
- MultipleItemPurchase
- Pallet
- Pickup
- Pipe
- PlaceableAI
- PlaceableAnimatedObjects
- PlaceableBeehive
- PlaceableBeehivePalletSpa...
- PlaceableBunkerSilo
- PlaceableBuyingStation
- PlaceableCartridgePlayer
- PlaceableChargingStation
- PlaceableClearAreas
- PlaceableColorable
- PlaceableDeletedNodes
- PlaceableDoghouse
- PlaceableDynamicallyLoade...
- PlaceableFarmhouse
- PlaceableFence
- PlaceableFoliageAreas
- PlaceableGreenhouse
- PlaceableHighPressureWash...
- PlaceableHotspots
- PlaceableHusbandry
- PlaceableHusbandryAnimals
- PlaceableHusbandryFeeding...
- PlaceableHusbandryFence
- PlaceableHusbandryFood
- PlaceableHusbandryLiquidM...
- PlaceableHusbandryMilk
- PlaceableHusbandryPallets
- PlaceableHusbandryStraw
- PlaceableHusbandryWater
- PlaceableIncomePerHour
- PlaceableIndoorAreas
- PlaceableInfoTrigger
- PlaceableLeveling
- PlaceableLights
- PlaceableManureHeap
- PlaceablePlacement
- PlaceableProductionPoint
- PlaceableSellingStation
- PlaceableSilo
- PlaceableSiloExtension
- PlaceableSolarPanels
- PlaceableTipOcclusionArea...
- PlaceableTrainSystem
- PlaceableTriggerMarkers
- PlaceableVine
- PlaceableWardrobe
- PlaceableWeatherStation
- PlaceableWeighingStation
- PlaceableWindTurbine
- PlaceableWorkshop
- Plow
- PlowPacker
- PowerConsumer
- PowerTakeOffs
- PrecisionFarmingStatistic
- PushHandTool
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- Rideable
- RidgeMarker
- Roller
- Ropes
- RTKStation
- SaltSpreader
- SemiTrailerFront
- Shovel
- SlopeCompensation
- SmartAttach
- SoilSampler
- SowingMachine
- SpeedRotatingParts
- SplineVehicle
- Sprayer
- StonePicker
- StrawBlower
- StumpCutter
- SupportVehicle
- Suspensions
- Tedder
- TensionBeltObject
- TensionBelts
- TestAreas
- TipOccluder
- Trailer
- TreePlanter
- TreeSaplingPallet
- TreeSaw
- TurnOnVehicle
- VariableWorkWidth
- VehicleSettings
- VineCutter
- VineDetector
- VinePrepruner
- Washable
- WaterTrailer
- Wearable
- Weeder
- WeedSpotSpray
- Wheels
- WindBending
- Windrower
- Wipers
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkMode
- WorkParticles
- 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
Baler
DescriptionSpecialization for balers allowing to pickup swaths and create physical bale objectsFunctions
- actionControllerBaleUnloadEvent
- actionEventToggleAutomaticDrop
- actionEventToggleSize
- actionEventUnloading
- createBale
- createDummyBale
- deleteDummyBale
- doCheckSpeedLimit
- dropBale
- dropBaleFromPlatform
- finishBale
- getAlarmTriggerIsActive
- getAllowDynamicMountFillLevelInfo
- getCanBeSelected
- getCanBeTurnedOn
- getCanUnloadUnfinishedBale
- getConsumingLoad
- getDefaultSpeedLimit
- getIsAttachedTo
- getIsBaleUnloading
- getIsFoldAllowed
- getIsSpeedRotatingPartActive
- getIsWorkAreaActive
- getSpecValueBaleSize
- getSpecValueBaleSizeRound
- getSpecValueBaleSizeSquare
- getTimeFromLevel
- handleUnloadingBaleEvent
- initSpecialization
- isUnloadingAllowed
- loadAlarmTrigger
- loadSpecValueBaleSize
- loadSpecValueBaleSizeRound
- loadSpecValueBaleSizeSquare
- loadSpeedRotatingPartFromXML
- moveBale
- moveBales
- onChangedFillType
- onDelete
- onEndWorkAreaProcessing
- onFillUnitFillLevelChanged
- onLoad
- onLoadFinished
- onPostLoad
- onReadStream
- onReadUpdateStream
- onRegisterActionEvents
- onRootVehicleChanged
- onStartWorkAreaProcessing
- onTurnedOff
- onTurnedOn
- onUpdate
- onUpdateTick
- onWriteStream
- onWriteUpdateStream
- prerequisitesPresent
- processBalerArea
- registerEventListeners
- registerFunctions
- registerOverwrittenFunctions
- saveToXMLFile
- setBalerAutomaticDrop
- setBaleTime
- setBaleTypeIndex
- setIsUnloadingBale
- updateActionEvents
- updateDummyBale
actionControllerBaleUnloadEvent
DescriptionDefinitionactionControllerBaleUnloadEvent()Code
1380 | function Baler:actionControllerBaleUnloadEvent(direction) |
1381 | if direction < 0 then |
1382 | local spec = self.spec_baler |
1383 | if self:isUnloadingAllowed() then |
1384 | if spec.allowsBaleUnloading then |
1385 | if spec.unloadingState == Baler.UNLOADING_CLOSED then |
1386 | if #spec.bales > 0 then |
1387 | self:setIsUnloadingBale(true) |
1388 | end |
1389 | end |
1390 | end |
1391 | end |
1392 | end |
1393 | end |
actionEventToggleAutomaticDrop
DescriptionDefinitionactionEventToggleAutomaticDrop()Code
2279 | function Baler.actionEventToggleAutomaticDrop(self, actionName, inputValue, callbackState, isAnalog) |
2280 | self:setBalerAutomaticDrop() |
2281 | end |
actionEventToggleSize
DescriptionDefinitionactionEventToggleSize()Code
2266 | function Baler.actionEventToggleSize(self, actionName, inputValue, callbackState, isAnalog) |
2267 | local spec = self.spec_baler |
2268 | |
2269 | local newIndex = spec.preSelectedBaleTypeIndex + 1 |
2270 | if newIndex > #spec.baleTypes then |
2271 | newIndex = 1 |
2272 | end |
2273 | |
2274 | self:setBaleTypeIndex(newIndex) |
2275 | end |
actionEventUnloading
DescriptionDefinitionactionEventUnloading()Code
2251 | function Baler.actionEventUnloading(self, actionName, inputValue, callbackState, isAnalog) |
2252 | local spec = self.spec_baler |
2253 | if not spec.hasPlatform then |
2254 | self:handleUnloadingBaleEvent() |
2255 | else |
2256 | if self:getCanUnloadUnfinishedBale() and not spec.platformReadyToDrop then |
2257 | self:handleUnloadingBaleEvent() |
2258 | else |
2259 | self:dropBaleFromPlatform(false) |
2260 | end |
2261 | end |
2262 | end |
createBale
DescriptionDefinitioncreateBale()Code
1646 | function Baler:createBale(baleFillType, fillLevel, baleServerId, baleTime, xmlFilename) |
1647 | local spec = self.spec_baler |
1648 | |
1649 | if spec.knotingAnimation ~= nil then |
1650 | self:playAnimation(spec.knotingAnimation, spec.knotingAnimationSpeed, nil, true) |
1651 | end |
1652 | |
1653 | local isValid = false |
1654 | local baleTypeDef = spec.baleTypes[spec.currentBaleTypeIndex] |
1655 | |
1656 | -- only delete dummy bale if dummy bale is converted to physical one, not if loaded from savegame to a specific time |
1657 | if baleTime == nil then |
1658 | self:deleteDummyBale(spec.dummyBale) |
1659 | end |
1660 | |
1661 | local bale = {} |
1662 | bale.filename = xmlFilename or spec.currentBaleXMLFilename |
1663 | bale.time = baleTime |
1664 | if bale.time == nil and spec.baleAnimLength ~= nil then |
1665 | bale.time = ((baleTypeDef.length * 0.5) / spec.baleAnimLength) |
1666 | end |
1667 | |
1668 | bale.fillType = baleFillType |
1669 | bale.fillLevel = fillLevel |
1670 | |
1671 | if spec.hasUnloadingAnimation then |
1672 | if self.isServer then |
1673 | local baleObject = Bale.new(self.isServer, self.isClient) |
1674 | local x, y, z = getWorldTranslation(baleTypeDef.baleRootNode) |
1675 | local rx, ry, rz = getWorldRotation(baleTypeDef.baleRootNode) |
1676 | if baleObject:loadFromConfigXML(bale.filename, x, y, z, rx, ry, rz) then |
1677 | baleObject:setFillType(baleFillType) |
1678 | baleObject:setFillLevel(fillLevel) |
1679 | |
1680 | local ownerFarmId = self:getLastTouchedFarmlandFarmId() |
1681 | if ownerFarmId == FarmManager.SPECTATOR_FARM_ID then |
1682 | ownerFarmId = self:getOwnerFarmId() -- in case of working on mission fields |
1683 | end |
1684 | baleObject:setOwnerFarmId(ownerFarmId, true) |
1685 | baleObject:setIsMissionBale(self:getLastActiveMissionWork()) |
1686 | |
1687 | baleObject:register() |
1688 | |
1689 | baleObject:mountKinematic(self, baleTypeDef.baleRootNode, 0, 0, 0, 0, 0, 0) |
1690 | |
1691 | bale.baleObject = baleObject |
1692 | isValid = true |
1693 | end |
1694 | else |
1695 | if baleServerId ~= nil then |
1696 | local baleObject = NetworkUtil.getObject(baleServerId) |
1697 | if baleObject ~= nil then |
1698 | bale.baleServerId = baleServerId |
1699 | baleObject:mountKinematic(self, baleTypeDef.baleRootNode, 0, 0, 0, 0, 0, 0) |
1700 | else |
1701 | spec.baleToMount = {baleServerId=baleServerId, jointNode=baleTypeDef.baleRootNode, baleInfo=bale} |
1702 | end |
1703 | |
1704 | isValid = true |
1705 | end |
1706 | end |
1707 | end |
1708 | |
1709 | if self.isServer and not spec.hasUnloadingAnimation then |
1710 | local x, y, z = getWorldTranslation(baleTypeDef.baleRootNode) |
1711 | local rx, ry, rz = getWorldRotation(baleTypeDef.baleRootNode) |
1712 | |
1713 | local baleJointNode = createTransformGroup("BaleJointTG") |
1714 | link(baleTypeDef.baleRootNode, baleJointNode) |
1715 | |
1716 | if bale.time ~= nil then |
1717 | local v = spec.baleAnimCurve:get(bale.time) |
1718 | setTranslation(baleJointNode, v[1], v[2], v[3]) |
1719 | setRotation(baleJointNode, v[4], v[5], v[6]) |
1720 | |
1721 | x, y, z = localToWorld(baleTypeDef.baleRootNode, v[1], v[2], v[3]) |
1722 | rx, ry, rz = localRotationToWorld(baleTypeDef.baleRootNode, v[4], v[5], v[6]) |
1723 | else |
1724 | setTranslation(baleJointNode, 0, 0, 0) |
1725 | setRotation(baleJointNode, 0, 0, 0) |
1726 | end |
1727 | |
1728 | local baleObject = Bale.new(self.isServer, self.isClient) |
1729 | if baleObject:loadFromConfigXML(bale.filename, x, y, z, rx, ry, rz) then |
1730 | baleObject:setFillType(baleFillType) |
1731 | baleObject:setFillLevel(fillLevel) |
1732 | |
1733 | local ownerFarmId = self:getLastTouchedFarmlandFarmId() |
1734 | if ownerFarmId == FarmManager.SPECTATOR_FARM_ID then |
1735 | ownerFarmId = self:getOwnerFarmId() -- in case of working on mission fields |
1736 | end |
1737 | baleObject:setOwnerFarmId(ownerFarmId, true) |
1738 | baleObject:setIsMissionBale(self:getLastActiveMissionWork()) |
1739 | |
1740 | baleObject:register() |
1741 | baleObject:setCanBeSold(false) |
1742 | |
1743 | local constr = JointConstructor.new() |
1744 | constr:setActors(baleTypeDef.baleNodeComponent, baleObject.nodeId) |
1745 | constr:setJointTransforms(baleJointNode, baleObject.nodeId) |
1746 | for i=1, 3 do |
1747 | constr:setRotationLimit(i-1, 0, 0) |
1748 | constr:setTranslationLimit(i-1, true, 0, 0) |
1749 | end |
1750 | constr:setEnableCollision(false) |
1751 | local baleJointIndex = constr:finalize() |
1752 | |
1753 | g_currentMission.itemSystem:removeItemToSave(baleObject) |
1754 | |
1755 | bale.baleJointNode = baleJointNode |
1756 | bale.baleJointIndex = baleJointIndex |
1757 | bale.baleObject = baleObject |
1758 | |
1759 | for i=1, #spec.bales do |
1760 | local otherBale = spec.bales[i] |
1761 | setPairCollision(otherBale.baleObject.nodeId, baleObject.nodeId, false) |
1762 | end |
1763 | |
1764 | isValid = true |
1765 | end |
1766 | elseif not self.isServer and not spec.hasUnloadingAnimation then |
1767 | isValid = true |
1768 | end |
1769 | |
1770 | if isValid then |
1771 | table.insert(spec.bales, bale) |
1772 | end |
1773 | |
1774 | return isValid |
1775 | end |
createDummyBale
DescriptionDefinitioncreateDummyBale()Code
1905 | function Baler:createDummyBale(dummyBaleData, fillTypeIndex) |
1906 | local spec = self.spec_baler |
1907 | |
1908 | if spec.currentBaleXMLFilename ~= nil then |
1909 | local baleId, sharedLoadRequestId = Bale.createDummyBale(spec.currentBaleXMLFilename, fillTypeIndex) |
1910 | local baleTypeDef = spec.baleTypes[spec.currentBaleTypeIndex] |
1911 | local linkNode = dummyBaleData.linkNode or baleTypeDef.baleNode |
1912 | link(linkNode, baleId) |
1913 | |
1914 | dummyBaleData.currentBale = baleId |
1915 | dummyBaleData.baleTypeDef = baleTypeDef |
1916 | dummyBaleData.currentBaleFillType = fillTypeIndex |
1917 | dummyBaleData.sharedLoadRequestId = sharedLoadRequestId |
1918 | end |
1919 | end |
deleteDummyBale
DescriptionDefinitiondeleteDummyBale()Code
1890 | function Baler:deleteDummyBale(dummyBaleData) |
1891 | if dummyBaleData ~= nil then |
1892 | if dummyBaleData.currentBale ~= nil then |
1893 | delete(dummyBaleData.currentBale) |
1894 | dummyBaleData.currentBale = nil |
1895 | end |
1896 | if dummyBaleData.sharedLoadRequestId ~= nil then |
1897 | g_i3DManager:releaseSharedI3DFile(dummyBaleData.sharedLoadRequestId) |
1898 | dummyBaleData.sharedLoadRequestId = nil |
1899 | end |
1900 | end |
1901 | end |
doCheckSpeedLimit
DescriptionDefinitiondoCheckSpeedLimit()Code
1397 | function Baler:doCheckSpeedLimit(superFunc) |
1398 | return superFunc(self) or (self:getIsTurnedOn() and self:getIsLowered()) |
1399 | end |
dropBale
DescriptionDefinitiondropBale()Code
1779 | function Baler:dropBale(baleIndex) |
1780 | local spec = self.spec_baler |
1781 | local bale = spec.bales[baleIndex] |
1782 | |
1783 | if self.isServer then |
1784 | local baleObject = bale.baleObject |
1785 | if bale.baleJointIndex ~= nil then |
1786 | removeJoint(bale.baleJointIndex) |
1787 | delete(bale.baleJointNode) |
1788 | g_currentMission.itemSystem:addItemToSave(bale.baleObject) |
1789 | else |
1790 | baleObject:unmountKinematic() |
1791 | end |
1792 | |
1793 | for i=1, #spec.bales do |
1794 | if i ~= baleIndex then |
1795 | local otherBale = spec.bales[i] |
1796 | setPairCollision(otherBale.baleObject.nodeId, baleObject.nodeId, true) |
1797 | end |
1798 | end |
1799 | |
1800 | if spec.lastBaleFillLevel ~= nil and #spec.bales == 1 then |
1801 | baleObject:setFillLevel(spec.lastBaleFillLevel) |
1802 | spec.lastBaleFillLevel = nil |
1803 | end |
1804 | |
1805 | baleObject:setCanBeSold(true) |
1806 | |
1807 | if baleObject.nodeId ~= nil and baleObject.nodeId ~= 0 then |
1808 | local baleTypeDef = spec.baleTypes[spec.currentBaleTypeIndex] |
1809 | |
1810 | -- release bale |
1811 | local x,y,z = getWorldTranslation(baleObject.nodeId) |
1812 | local vx,vy,vz = getVelocityAtWorldPos(baleTypeDef.baleNodeComponent or self.components[1].node, x,y,z) |
1813 | setLinearVelocity(baleObject.nodeId, vx,vy,vz) |
1814 | end |
1815 | |
1816 | g_farmManager:updateFarmStats(self:getLastTouchedFarmlandFarmId(), "baleCount", 1) |
1817 | else |
1818 | if spec.hasUnloadingAnimation then |
1819 | -- check if it is still available (it could already be picked up by a wrapper and be deleted) |
1820 | local baleObject = NetworkUtil.getObject(bale.baleServerId) |
1821 | if baleObject ~= nil then |
1822 | baleObject:unmountKinematic() |
1823 | end |
1824 | end |
1825 | end |
1826 | |
1827 | table.remove(spec.bales, baleIndex) |
1828 | |
1829 | if spec.hasPlatform then |
1830 | if not spec.platformReadyToDrop then |
1831 | spec.platformReadyToDrop = true |
1832 | end |
1833 | |
1834 | if spec.hasDynamicMountPlatform then |
1835 | -- 5 frames delay to give the bale time to be added to physics and change from kinematic to dynamic |
1836 | spec.platformMountDelay = 5 |
1837 | end |
1838 | end |
1839 | end |
dropBaleFromPlatform
DescriptionDefinitiondropBaleFromPlatform()Code
1457 | function Baler:dropBaleFromPlatform(waitForNextBale, noEventSend) |
1458 | local spec = self.spec_baler |
1459 | if spec.platformReadyToDrop then |
1460 | self:setAnimationTime(spec.platformAnimation, 0, false) |
1461 | self:playAnimation(spec.platformAnimation, 1, self:getAnimationTime(spec.platformAnimation), true) |
1462 | if waitForNextBale == true then |
1463 | self:setAnimationStopTime(spec.platformAnimation, spec.platformAnimationNextBaleTime) |
1464 | end |
1465 | spec.platformReadyToDrop = false |
1466 | spec.platformDropInProgress = true |
1467 | |
1468 | -- unmount bales on platform |
1469 | if self.isServer then |
1470 | if spec.hasDynamicMountPlatform then |
1471 | self:forceUnmountDynamicMountedObjects() |
1472 | end |
1473 | end |
1474 | end |
1475 | |
1476 | BalerDropFromPlatformEvent.sendEvent(self, waitForNextBale, noEventSend) |
1477 | end |
finishBale
DescriptionDefinitionfinishBale()Code
1607 | function Baler:finishBale() |
1608 | local spec = self.spec_baler |
1609 | if spec.baleTypes ~= nil then |
1610 | local fillTypeIndex = self:getFillUnitFillType(spec.fillUnitIndex) |
1611 | if not spec.hasUnloadingAnimation then |
1612 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, -math.huge, fillTypeIndex, ToolType.UNDEFINED) |
1613 | spec.buffer.unloadingStarted = false |
1614 | |
1615 | for fillType, _ in pairs(spec.pickupFillTypes) do |
1616 | spec.pickupFillTypes[fillType] = 0 |
1617 | end |
1618 | |
1619 | if self:createBale(fillTypeIndex, self:getFillUnitCapacity(spec.fillUnitIndex)) then |
1620 | local bale = spec.bales[#spec.bales] |
1621 | |
1622 | -- note: spec.bales[numBales] can not be accessed anymore since the bale might be dropped already |
1623 | g_server:broadcastEvent(BalerCreateBaleEvent.new(self, fillTypeIndex, bale.time), nil, nil, self) |
1624 | |
1625 | if self:getFillUnitFillLevel(spec.fillUnitIndex) == 0 then |
1626 | if spec.preSelectedBaleTypeIndex ~= spec.currentBaleTypeIndex then |
1627 | self:setBaleTypeIndex(spec.preSelectedBaleTypeIndex, true) |
1628 | end |
1629 | end |
1630 | else |
1631 | Logging.error("Failed to create bale!") |
1632 | end |
1633 | else |
1634 | if self:createBale(fillTypeIndex, self:getFillUnitCapacity(spec.fillUnitIndex)) then |
1635 | local bale = spec.bales[#spec.bales] |
1636 | g_server:broadcastEvent(BalerCreateBaleEvent.new(self, fillTypeIndex, 0, NetworkUtil.getObjectId(bale.baleObject)), nil, nil, self) |
1637 | else |
1638 | Logging.error("Failed to create bale!") |
1639 | end |
1640 | end |
1641 | end |
1642 | end |
getAlarmTriggerIsActive
DescriptionDefinitiongetAlarmTriggerIsActive()Code
2060 | function Baler:getAlarmTriggerIsActive(superFunc, alarmTrigger) |
2061 | local ret = superFunc(self, alarmTrigger) |
2062 | |
2063 | if alarmTrigger.needsBaleLoaded then |
2064 | if self.spec_baler ~= nil then |
2065 | if #self.spec_baler.bales == 0 then |
2066 | return false |
2067 | end |
2068 | end |
2069 | end |
2070 | |
2071 | return ret |
2072 | end |
getAllowDynamicMountFillLevelInfo
DescriptionDefinitiongetAllowDynamicMountFillLevelInfo()Code
2054 | function Baler:getAllowDynamicMountFillLevelInfo(superFunc) |
2055 | return false |
2056 | end |
getCanBeSelected
DescriptionDefinitiongetCanBeSelected()Code
2031 | function Baler:getCanBeSelected(superFunc) |
2032 | return true |
2033 | end |
getCanBeTurnedOn
DescriptionDefinitiongetCanBeTurnedOn()Code
1954 | function Baler:getCanBeTurnedOn(superFunc) |
1955 | local spec = self.spec_baler |
1956 | |
1957 | if spec.isBaleUnloading then |
1958 | return false |
1959 | end |
1960 | |
1961 | return superFunc(self) |
1962 | end |
getCanUnloadUnfinishedBale
DescriptionDefinitiongetCanUnloadUnfinishedBale()Code
1923 | function Baler:getCanUnloadUnfinishedBale() |
1924 | local spec = self.spec_baler |
1925 | return spec.canUnloadUnfinishedBale and self:getFillUnitFillLevel(spec.fillUnitIndex) > spec.unfinishedBaleThreshold |
1926 | end |
getConsumingLoad
DescriptionDefinitiongetConsumingLoad()Code
2020 | function Baler:getConsumingLoad(superFunc) |
2021 | local value, count = superFunc(self) |
2022 | |
2023 | local spec = self.spec_baler |
2024 | local loadPercentage = spec.pickUpLitersBuffer:get(1000) / spec.maxPickupLitersPerSecond |
2025 | |
2026 | return value+loadPercentage, count+1 |
2027 | end |
getDefaultSpeedLimit
DescriptionDefinitiongetDefaultSpeedLimit()Code
1988 | function Baler.getDefaultSpeedLimit() |
1989 | return 25 |
1990 | end |
getIsAttachedTo
DescriptionDefinitiongetIsAttachedTo()Code
2037 | function Baler:getIsAttachedTo(superFunc, vehicle) |
2038 | if superFunc(self, vehicle) then |
2039 | return true |
2040 | end |
2041 | |
2042 | local spec = self.spec_baler |
2043 | for i=1, #spec.bales do |
2044 | if spec.bales[i].baleObject == vehicle then |
2045 | return true |
2046 | end |
2047 | end |
2048 | |
2049 | return false |
2050 | end |
getIsBaleUnloading
DescriptionDefinitiongetIsBaleUnloading()Code
1532 | function Baler:getIsBaleUnloading() |
1533 | return self.spec_baler.isBaleUnloading |
1534 | end |
getIsFoldAllowed
DescriptionDefinitiongetIsFoldAllowed()Code
1210 | function Baler:getIsFoldAllowed(superFunc, direction, onAiTurnOn) |
1211 | local spec = self.spec_baler |
1212 | |
1213 | if #spec.bales > 0 and self:getFillUnitFillLevel(spec.fillUnitIndex) > spec.baleFoldThreshold then |
1214 | return false, spec.texts.warningFoldingBaleLoaded |
1215 | end |
1216 | |
1217 | if #spec.bales > 1 then |
1218 | return false, spec.texts.warningFoldingBaleLoaded |
1219 | end |
1220 | |
1221 | if self:getIsTurnedOn() then |
1222 | return false, spec.texts.warningFoldingTurnedOn |
1223 | end |
1224 | |
1225 | if spec.hasPlatform then |
1226 | if spec.platformReadyToDrop or spec.platformDropInProgress then |
1227 | return false, spec.texts.warningFoldingBaleLoaded |
1228 | end |
1229 | end |
1230 | |
1231 | return superFunc(self, direction, onAiTurnOn) |
1232 | end |
getIsSpeedRotatingPartActive
DescriptionDefinitiongetIsSpeedRotatingPartActive()Code
1974 | function Baler:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart) |
1975 | local spec = self.spec_baler |
1976 | |
1977 | if speedRotatingPart.rotateOnlyIfFillLevelIncreased ~= nil then |
1978 | if speedRotatingPart.rotateOnlyIfFillLevelIncreased and spec.lastAreaBiggerZeroTime == 0 then |
1979 | return false |
1980 | end |
1981 | end |
1982 | |
1983 | return superFunc(self, speedRotatingPart) |
1984 | end |
getIsWorkAreaActive
DescriptionDefinitiongetIsWorkAreaActive()Code
1994 | function Baler:getIsWorkAreaActive(superFunc, workArea) |
1995 | local spec = self.spec_baler |
1996 | |
1997 | if not g_currentMission.slotSystem:getCanAddLimitedObjects(SlotSystem.LIMITED_OBJECT_BALE, 1) and self:getIsTurnedOn() then |
1998 | return false |
1999 | end |
2000 | |
2001 | if self:getFillUnitFreeCapacity(spec.buffer.fillUnitIndex or spec.fillUnitIndex) == 0 then |
2002 | return false |
2003 | end |
2004 | |
2005 | if self.allowPickingUp ~= nil and not self:allowPickingUp() then |
2006 | return false |
2007 | end |
2008 | |
2009 | if spec.hasUnloadingAnimation and not spec.nonStopBaling then |
2010 | if #spec.bales > 0 or spec.unloadingState ~= Baler.UNLOADING_CLOSED then |
2011 | return false |
2012 | end |
2013 | end |
2014 | |
2015 | return superFunc(self, workArea) |
2016 | end |
getSpecValueBaleSize
DescriptionDefinitiongetSpecValueBaleSize()Code
2374 | function Baler.getSpecValueBaleSize(storeItem, realItem, configurations, saleItem, returnValues, returnRange, roundBale) |
2375 | local baleSizeAttributes = roundBale and storeItem.specs.balerBaleSizeRound or storeItem.specs.balerBaleSizeSquare |
2376 | if baleSizeAttributes ~= nil then |
2377 | local minValue = baleSizeAttributes.isRoundBaler and baleSizeAttributes.minDiameter or baleSizeAttributes.minLength |
2378 | local maxValue = baleSizeAttributes.isRoundBaler and baleSizeAttributes.maxDiameter or baleSizeAttributes.maxLength |
2379 | |
2380 | if returnValues == nil or not returnValues then |
2381 | local unit = g_i18n:getText("unit_cmShort") |
2382 | local size |
2383 | if maxValue ~= minValue then |
2384 | size = string.format("%d%s-%d%s", minValue * 100, unit, maxValue * 100, unit) |
2385 | else |
2386 | size = string.format("%d%s", minValue * 100, unit) |
2387 | end |
2388 | |
2389 | return size |
2390 | else |
2391 | if returnRange == true and maxValue ~= minValue then |
2392 | return minValue * 100, maxValue * 100, g_i18n:getText("unit_cmShort") |
2393 | else |
2394 | return minValue * 100, g_i18n:getText("unit_cmShort") |
2395 | end |
2396 | end |
2397 | else |
2398 | if returnValues and returnRange then |
2399 | return 0, 0, "" |
2400 | elseif returnValues then |
2401 | return 0, "" |
2402 | else |
2403 | return "" |
2404 | end |
2405 | end |
2406 | end |
getSpecValueBaleSizeRound
DescriptionDefinitiongetSpecValueBaleSizeRound()Code
2428 | function Baler.getSpecValueBaleSizeRound(storeItem, realItem, configurations, saleItem, returnValues, returnRange) |
2429 | if storeItem.specs.balerBaleSizeRound ~= nil then |
2430 | if storeItem.specs.balerBaleSizeRound.isRoundBaler then |
2431 | return Baler.getSpecValueBaleSize(storeItem, realItem, configurations, saleItem, returnValues, returnRange, true) |
2432 | end |
2433 | end |
2434 | end |
getSpecValueBaleSizeSquare
DescriptionDefinitiongetSpecValueBaleSizeSquare()Code
2438 | function Baler.getSpecValueBaleSizeSquare(storeItem, realItem, configurations, saleItem, returnValues, returnRange) |
2439 | if storeItem.specs.balerBaleSizeSquare ~= nil then |
2440 | if not storeItem.specs.balerBaleSizeSquare.isRoundBaler then |
2441 | return Baler.getSpecValueBaleSize(storeItem, realItem, configurations, saleItem, returnValues, returnRange, false) |
2442 | end |
2443 | end |
2444 | end |
getTimeFromLevel
DescriptionDefinitiongetTimeFromLevel()Code
1538 | function Baler:getTimeFromLevel(level) |
1539 | local spec = self.spec_baler |
1540 | |
1541 | -- level = capacity -> time = firstBaleMarker |
1542 | -- level = 0 -> time = 0 |
1543 | if spec.currentBaleTypeDefinition ~= nil then |
1544 | local baleLength = spec.currentBaleTypeDefinition.length + spec.baleAnimSpacing |
1545 | return level / self:getFillUnitCapacity(spec.fillUnitIndex) * (baleLength / spec.baleAnimLength) |
1546 | end |
1547 | return 0 |
1548 | end |
handleUnloadingBaleEvent
DescriptionDefinitionhandleUnloadingBaleEvent()Code
1438 | function Baler:handleUnloadingBaleEvent() |
1439 | local spec = self.spec_baler |
1440 | if self:isUnloadingAllowed() then |
1441 | if spec.hasUnloadingAnimation or spec.allowsBaleUnloading then |
1442 | if spec.unloadingState == Baler.UNLOADING_CLOSED then |
1443 | if #spec.bales > 0 or self:getCanUnloadUnfinishedBale() then |
1444 | self:setIsUnloadingBale(true) |
1445 | end |
1446 | elseif spec.unloadingState == Baler.UNLOADING_OPEN then |
1447 | if spec.hasUnloadingAnimation then |
1448 | self:setIsUnloadingBale(false) |
1449 | end |
1450 | end |
1451 | end |
1452 | end |
1453 | end |
initSpecialization
DescriptionDefinitioninitSpecialization()Code
27 | function Baler.initSpecialization() |
28 | g_workAreaTypeManager:addWorkAreaType("baler", false) |
29 | |
30 | g_storeManager:addSpecType("balerBaleSizeRound", "shopListAttributeIconBaleSizeRound", Baler.loadSpecValueBaleSizeRound, Baler.getSpecValueBaleSizeRound, "vehicle") |
31 | g_storeManager:addSpecType("balerBaleSizeSquare", "shopListAttributeIconBaleSizeSquare", Baler.loadSpecValueBaleSizeSquare, Baler.getSpecValueBaleSizeSquare, "vehicle") |
32 | |
33 | local schema = Vehicle.xmlSchema |
34 | schema:setXMLSpecializationType("Baler") |
35 | |
36 | schema:register(XMLValueType.FLOAT, "vehicle.baler#fillScale", "Fill scale", 1) |
37 | schema:register(XMLValueType.INT, "vehicle.baler#fillUnitIndex", "Fill unit index", 1) |
38 | schema:register(XMLValueType.FLOAT, "vehicle.baler.baleAnimation#spacing", "Spacing between bales", 0) |
39 | schema:register(XMLValueType.FLOAT, "vehicle.baler.baleAnimation.key(?)#time", "Key time") |
40 | schema:register(XMLValueType.VECTOR_TRANS, "vehicle.baler.baleAnimation.key(?)#pos", "Key position") |
41 | schema:register(XMLValueType.VECTOR_ROT, "vehicle.baler.baleAnimation.key(?)#rot", "Key rotation") |
42 | |
43 | schema:register(XMLValueType.STRING, "vehicle.baler.baleAnimation#closeAnimationName", "Close animation name") |
44 | schema:register(XMLValueType.FLOAT, "vehicle.baler.baleAnimation#closeAnimationSpeed", "Close animation speed", 1) |
45 | |
46 | schema:register(XMLValueType.BOOL, "vehicle.baler.automaticDrop#enabled", "Automatic drop default enabled", "true on mobile") |
47 | schema:register(XMLValueType.BOOL, "vehicle.baler.automaticDrop#toggleable", "Automatic bale drop can be toggled", "false on mobile") |
48 | |
49 | |
50 | schema:register(XMLValueType.L10N_STRING, "vehicle.baler.baleTypes#changeText", "Change bale size text", "action_changeBaleSize") |
51 | schema:register(XMLValueType.BOOL, "vehicle.baler.baleTypes.baleType(?)#isRoundBale", "Is round bale", false) |
52 | schema:register(XMLValueType.FLOAT, "vehicle.baler.baleTypes.baleType(?)#width", "Bale width", 1.2) |
53 | schema:register(XMLValueType.FLOAT, "vehicle.baler.baleTypes.baleType(?)#height", "Bale height", 0.9) |
54 | schema:register(XMLValueType.FLOAT, "vehicle.baler.baleTypes.baleType(?)#length", "Bale length", 2.4) |
55 | schema:register(XMLValueType.FLOAT, "vehicle.baler.baleTypes.baleType(?)#diameter", "Bale diameter", 2.8) |
56 | schema:register(XMLValueType.BOOL, "vehicle.baler.baleTypes.baleType(?)#isDefault", "Bale type is selected by default", false) |
57 | |
58 | schema:register(XMLValueType.NODE_INDEX, "vehicle.baler.baleTypes.baleType(?).nodes#baleNode", "Bale link node") |
59 | schema:register(XMLValueType.NODE_INDEX, "vehicle.baler.baleTypes.baleType(?).nodes#baleRootNode", "Bale root node", "Same as baleNode") |
60 | schema:register(XMLValueType.NODE_INDEX, "vehicle.baler.baleTypes.baleType(?).nodes#scaleNode", "Bale scale node") |
61 | schema:register(XMLValueType.VECTOR_3, "vehicle.baler.baleTypes.baleType(?).nodes#scaleComponents", "Bale scale component") |
62 | |
63 | schema:register(XMLValueType.STRING, "vehicle.baler.baleTypes.baleType(?).animations#fillAnimation", "Fill animation while this bale type is active") |
64 | schema:register(XMLValueType.STRING, "vehicle.baler.baleTypes.baleType(?).animations#unloadAnimation", "Unload animation while this bale type is active") |
65 | schema:register(XMLValueType.FLOAT, "vehicle.baler.baleTypes.baleType(?).animations#unloadAnimationSpeed", "Unload animation speed", 1) |
66 | schema:register(XMLValueType.TIME, "vehicle.baler.baleTypes.baleType(?).animations#dropAnimationTime", "Specific time in #unloadAnimation when to drop the bale", "At the end of the unloading animation") |
67 | |
68 | schema:register(XMLValueType.NODE_INDEX, "vehicle.baler.baleTypes.baleType(?).detailVisibilityCutNode(?)#node", "Reference node for details visibility cut") |
69 | schema:register(XMLValueType.INT, "vehicle.baler.baleTypes.baleType(?).detailVisibilityCutNode(?)#axis", "Axis of visibility cut [1, 3]", 3) |
70 | schema:register(XMLValueType.INT, "vehicle.baler.baleTypes.baleType(?).detailVisibilityCutNode(?)#direction", "Direction of visibility cut [-1, 1]", 1) |
71 | |
72 | ObjectChangeUtil.registerObjectChangeXMLPaths(schema, "vehicle.baler.baleTypes.baleType(?)") |
73 | |
74 | schema:register(XMLValueType.FLOAT, "vehicle.baler#unfinishedBaleThreshold", "Threshold to unload a unfinished bale", 2000) |
75 | schema:register(XMLValueType.BOOL, "vehicle.baler#canUnloadUnfinishedBale", "Can unload unfinished bale", false) |
76 | |
77 | SoundManager.registerSampleXMLPaths(schema, "vehicle.baler.sounds", "work") |
78 | SoundManager.registerSampleXMLPaths(schema, "vehicle.baler.sounds", "eject") |
79 | SoundManager.registerSampleXMLPaths(schema, "vehicle.baler.sounds", "unload") |
80 | SoundManager.registerSampleXMLPaths(schema, "vehicle.baler.sounds", "door") |
81 | SoundManager.registerSampleXMLPaths(schema, "vehicle.baler.sounds", "knotCleaning") |
82 | |
83 | AnimationManager.registerAnimationNodesXMLPaths(schema, "vehicle.baler.animationNodes") |
84 | AnimationManager.registerAnimationNodesXMLPaths(schema, "vehicle.baler.unloadAnimationNodes") |
85 | |
86 | EffectManager.registerEffectXMLPaths(schema, "vehicle.baler.fillEffect") |
87 | |
88 | schema:register(XMLValueType.STRING, "vehicle.baler.knotingAnimation#name", "Knoting animation name") |
89 | schema:register(XMLValueType.FLOAT, "vehicle.baler.knotingAnimation#speed", "Knoting animation speed", 1) |
90 | |
91 | schema:register(XMLValueType.STRING, "vehicle.baler.compactingAnimation#name", "Compacting animation name") |
92 | schema:register(XMLValueType.FLOAT, "vehicle.baler.compactingAnimation#interval", "Compacting interval", 60) |
93 | schema:register(XMLValueType.FLOAT, "vehicle.baler.compactingAnimation#compactTime", "Compacting time", 5) |
94 | schema:register(XMLValueType.FLOAT, "vehicle.baler.compactingAnimation#speed", "Compacting animation speed", 1) |
95 | schema:register(XMLValueType.FLOAT, "vehicle.baler.compactingAnimation#minFillLevelTime", "Compacting min. fill level animation target time", 1) |
96 | schema:register(XMLValueType.FLOAT, "vehicle.baler.compactingAnimation#maxFillLevelTime", "Compacting max. fill level animation target time", 0.1) |
97 | |
98 | schema:register(XMLValueType.STRING, "vehicle.baler#maxPickupLitersPerSecond", "Max pickup liters per second", 500) |
99 | |
100 | schema:register(XMLValueType.BOOL, "vehicle.baler.baleUnloading#allowed", "Bale unloading allowed", false) |
101 | schema:register(XMLValueType.FLOAT, "vehicle.baler.baleUnloading#time", "Bale unloading time", 4) |
102 | schema:register(XMLValueType.FLOAT, "vehicle.baler.baleUnloading#foldThreshold", "Bale unloading fold threshold", 0.25) |
103 | |
104 | schema:register(XMLValueType.L10N_STRING, "vehicle.baler.automaticDrop#textPos", "Positive toggle automatic drop text", "action_toggleAutomaticBaleDropPos") |
105 | schema:register(XMLValueType.L10N_STRING, "vehicle.baler.automaticDrop#textNeg", "Negative toggle automatic drop text", "action_toggleAutomaticBaleDropNeg") |
106 | |
107 | schema:register(XMLValueType.STRING, "vehicle.baler.platform#animationName", "Platform animation") |
108 | schema:register(XMLValueType.FLOAT, "vehicle.baler.platform#nextBaleTime", "Animation time when directly the next bale is unloaded after dropping from platform", 0) |
109 | schema:register(XMLValueType.BOOL, "vehicle.baler.platform#automaticDrop", "Bale is automatically dropped from platform", "true on mobile") |
110 | schema:register(XMLValueType.FLOAT, "vehicle.baler.platform#aiSpeed", "Speed of AI while dropping a bale from platform (km/h)", 3) |
111 | |
112 | schema:register(XMLValueType.INT, "vehicle.baler.buffer#fillUnitIndex", "Buffer fill unit index") |
113 | schema:register(XMLValueType.FLOAT, "vehicle.baler.buffer#capacityPercentage", "If set, this percentage of the bale capacity is set for the buffer. If not set the defined capacity from the xml is used.") |
114 | schema:register(XMLValueType.TIME, "vehicle.baler.buffer#overloadingDuration", "Duration of overloading from buffer to baler unit (sec)", 0.5) |
115 | schema:register(XMLValueType.BOOL, "vehicle.baler.buffer#fillMainUnitAfterOverload", "After overloading the full buffer to the main unit it will continue filling the main unit until it's full", false) |
116 | schema:register(XMLValueType.STRING, "vehicle.baler.buffer#balerDisplayType", "Forced fill type to display on baler unit") |
117 | |
118 | schema:register(XMLValueType.NODE_INDEX, "vehicle.baler.buffer.dummyBale#node", "Dummy bale link node") |
119 | schema:register(XMLValueType.VECTOR_3, "vehicle.baler.buffer.dummyBale#scaleComponents", "Dummy bale link scale components", "1 1 0") |
120 | |
121 | schema:register(XMLValueType.STRING, "vehicle.baler.buffer.overloadAnimation#name", "Name of overload animation") |
122 | schema:register(XMLValueType.FLOAT, "vehicle.baler.buffer.overloadAnimation#speedScale", "Speed of overload animation", 1) |
123 | |
124 | schema:register(XMLValueType.STRING, "vehicle.baler.buffer.loadingStateAnimation#name", "Name of loading state animation") |
125 | schema:register(XMLValueType.FLOAT, "vehicle.baler.buffer.loadingStateAnimation#speedScale", "Speed of loading state animation", 1) |
126 | |
127 | schema:register(XMLValueType.FLOAT, "vehicle.baler.variableSpeedLimit#targetLiterPerSecond", "Target liters per second", 200) |
128 | schema:register(XMLValueType.TIME, "vehicle.baler.variableSpeedLimit#changeInterval", "Interval which adjusts speed limit to conditions", 1) |
129 | schema:register(XMLValueType.FLOAT, "vehicle.baler.variableSpeedLimit#minSpeedLimit", "Min. speed limit", 5) |
130 | schema:register(XMLValueType.FLOAT, "vehicle.baler.variableSpeedLimit#maxSpeedLimit", "Max. speed limit", 15) |
131 | schema:register(XMLValueType.FLOAT, "vehicle.baler.variableSpeedLimit#defaultSpeedLimit", "Default speed limit", 10) |
132 | schema:register(XMLValueType.STRING, "vehicle.baler.variableSpeedLimit.target(?)#fillType", "Name of fill type") |
133 | schema:register(XMLValueType.FLOAT, "vehicle.baler.variableSpeedLimit.target(?)#targetLiterPerSecond", "Target liters per second with this fill type", 200) |
134 | schema:register(XMLValueType.FLOAT, "vehicle.baler.variableSpeedLimit.target(?)#defaultSpeedLimit", "Default speed limit with this fill type", 10) |
135 | |
136 | schema:register(XMLValueType.INT, "vehicle.baler.additives#fillUnitIndex", "Additives fill unit index") |
137 | schema:register(XMLValueType.FLOAT, "vehicle.baler.additives#usage", "Usage per picked up liter", 0.0000275) |
138 | schema:register(XMLValueType.STRING, "vehicle.baler.additives#fillTypes", "Fill types to apply additives", "GRASS_WINDROW") |
139 | |
140 | schema:register(XMLValueType.BOOL, FillUnit.ALARM_TRIGGER_XML_KEY .. "#needsBaleLoaded", "Alarm triggers only when a full bale is loaded", false) |
141 | |
142 | schema:setXMLSpecializationType() |
143 | |
144 | local schemaSavegame = Vehicle.xmlSchemaSavegame |
145 | schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).baler#numBales", "Number of bales") |
146 | schemaSavegame:register(XMLValueType.STRING, "vehicles.vehicle(?).baler.bale(?)#filename", "XML Filename of bale") |
147 | schemaSavegame:register(XMLValueType.STRING, "vehicles.vehicle(?).baler.bale(?)#fillType", "Bale fill type index") |
148 | schemaSavegame:register(XMLValueType.FLOAT, "vehicles.vehicle(?).baler.bale(?)#fillLevel", "Bale fill level") |
149 | schemaSavegame:register(XMLValueType.FLOAT, "vehicles.vehicle(?).baler.bale(?)#baleTime", "Bale time") |
150 | |
151 | schemaSavegame:register(XMLValueType.BOOL, "vehicles.vehicle(?).baler#platformReadyToDrop", "Platform is ready to drop", false) |
152 | schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).baler#baleTypeIndex", "Current bale type index", 1) |
153 | schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).baler#preSelectedBaleTypeIndex", "Pre selected bale type index", 1) |
154 | schemaSavegame:register(XMLValueType.FLOAT, "vehicles.vehicle(?).baler#fillUnitCapacity", "Current baler capacity depending on bale size") |
155 | schemaSavegame:register(XMLValueType.BOOL, "vehicles.vehicle(?).baler#bufferUnloadingStarted", "Baler buffer unloading in progress") |
156 | end |
isUnloadingAllowed
DescriptionDefinitionisUnloadingAllowed()Code
1418 | function Baler:isUnloadingAllowed() |
1419 | local spec = self.spec_baler |
1420 | |
1421 | if spec.platformReadyToDrop or spec.platformDropInProgress then |
1422 | -- block only opening of baler |
1423 | if spec.unloadingState ~= Baler.UNLOADING_OPEN then |
1424 | return false |
1425 | end |
1426 | end |
1427 | |
1428 | if self.spec_baleWrapper == nil then |
1429 | return not spec.allowsBaleUnloading or (spec.allowsBaleUnloading and not self:getIsTurnedOn() and not spec.isBaleUnloading) |
1430 | end |
1431 | |
1432 | return self:allowsGrabbingBale() |
1433 | end |
loadAlarmTrigger
DescriptionDefinitionloadAlarmTrigger()Code
2076 | function Baler:loadAlarmTrigger(superFunc, xmlFile, key, alarmTrigger, fillUnit) |
2077 | local ret = superFunc(self, xmlFile, key, alarmTrigger, fillUnit) |
2078 | |
2079 | alarmTrigger.needsBaleLoaded = xmlFile:getValue(key .. "#needsBaleLoaded", false) |
2080 | |
2081 | return ret |
2082 | end |
loadSpecValueBaleSize
DescriptionDefinitionloadSpecValueBaleSize()Code
2349 | function Baler.loadSpecValueBaleSize(xmlFile, customEnvironment, baseDir) |
2350 | local rootName = xmlFile:getRootName() |
2351 | |
2352 | local baleSizeAttributes = {} |
2353 | baleSizeAttributes.isRoundBaler = false |
2354 | baleSizeAttributes.minDiameter, baleSizeAttributes.maxDiameter = math.huge, -math.huge |
2355 | baleSizeAttributes.minLength, baleSizeAttributes.maxLength = math.huge, -math.huge |
2356 | xmlFile:iterate(rootName..".baler.baleTypes.baleType", function(_, key) |
2357 | baleSizeAttributes.isRoundBaler = xmlFile:getValue(key.."#isRoundBale", baleSizeAttributes.isRoundBaler) |
2358 | local diameter = MathUtil.round(xmlFile:getValue(key.."#diameter", 0), 2) |
2359 | baleSizeAttributes.minDiameter = math.min(baleSizeAttributes.minDiameter, diameter) |
2360 | baleSizeAttributes.maxDiameter = math.max(baleSizeAttributes.maxDiameter, diameter) |
2361 | |
2362 | local length = MathUtil.round(xmlFile:getValue(key.."#length", 0), 2) |
2363 | baleSizeAttributes.minLength = math.min(baleSizeAttributes.minLength, length) |
2364 | baleSizeAttributes.maxLength = math.max(baleSizeAttributes.maxLength, length) |
2365 | end) |
2366 | |
2367 | if baleSizeAttributes.minDiameter ~= math.huge or baleSizeAttributes.minLength ~= math.huge then |
2368 | return baleSizeAttributes |
2369 | end |
2370 | end |
loadSpecValueBaleSizeRound
DescriptionDefinitionloadSpecValueBaleSizeRound()Code
2410 | function Baler.loadSpecValueBaleSizeRound(xmlFile, customEnvironment, baseDir) |
2411 | local baleSizeAttributes = Baler.loadSpecValueBaleSize(xmlFile, customEnvironment, baseDir) |
2412 | if baleSizeAttributes ~= nil and baleSizeAttributes.isRoundBaler then |
2413 | return baleSizeAttributes |
2414 | end |
2415 | end |
loadSpecValueBaleSizeSquare
DescriptionDefinitionloadSpecValueBaleSizeSquare()Code
2419 | function Baler.loadSpecValueBaleSizeSquare(xmlFile, customEnvironment, baseDir) |
2420 | local baleSizeAttributes = Baler.loadSpecValueBaleSize(xmlFile, customEnvironment, baseDir) |
2421 | if baleSizeAttributes ~= nil and not baleSizeAttributes.isRoundBaler then |
2422 | return baleSizeAttributes |
2423 | end |
2424 | end |
loadSpeedRotatingPartFromXML
DescriptionDefinitionloadSpeedRotatingPartFromXML()Code
1966 | function Baler:loadSpeedRotatingPartFromXML(superFunc, speedRotatingPart, xmlFile, key) |
1967 | speedRotatingPart.rotateOnlyIfFillLevelIncreased = xmlFile:getValue(key .. "#rotateOnlyIfFillLevelIncreased", false) |
1968 | |
1969 | return superFunc(self, speedRotatingPart, xmlFile, key) |
1970 | end |
moveBale
DescriptionDefinitionmoveBale()Code
1562 | function Baler:moveBale(i, dt, noEventSend) |
1563 | local spec = self.spec_baler |
1564 | |
1565 | local bale = spec.bales[i] |
1566 | self:setBaleTime(i, bale.time + dt, noEventSend) |
1567 | end |
moveBales
DescriptionDefinitionmoveBales()Code
1552 | function Baler:moveBales(dt) |
1553 | local spec = self.spec_baler |
1554 | |
1555 | for i=#spec.bales, 1, -1 do |
1556 | self:moveBale(i, dt) |
1557 | end |
1558 | end |
onChangedFillType
DescriptionDefinitiononChangedFillType()Code
1236 | function Baler:onChangedFillType(fillUnitIndex, fillTypeIndex, oldFillTypeIndex) |
1237 | local spec = self.spec_baler |
1238 | |
1239 | if fillUnitIndex == spec.fillUnitIndex or fillUnitIndex == spec.buffer.fillUnitIndex then |
1240 | if fillTypeIndex ~= FillType.UNKNOWN then |
1241 | local baleTypeDef = spec.baleTypes[spec.currentBaleTypeIndex] |
1242 | spec.currentBaleTypeDefinition = baleTypeDef |
1243 | |
1244 | spec.currentBaleXMLFilename, spec.currentBaleIndex = g_baleManager:getBaleXMLFilename(fillTypeIndex, |
1245 | baleTypeDef.isRoundBale, |
1246 | baleTypeDef.width, |
1247 | baleTypeDef.height, |
1248 | baleTypeDef.length, |
1249 | baleTypeDef.diameter, |
1250 | self.customEnvironment) |
1251 | |
1252 | local baleCapacity = g_baleManager:getBaleCapacityByBaleIndex(spec.currentBaleIndex, fillTypeIndex) |
1253 | if fillUnitIndex == spec.fillUnitIndex then |
1254 | self:setFillUnitCapacity(fillUnitIndex, baleCapacity, false) |
1255 | else |
1256 | if spec.buffer.capacityPercentage ~= nil then |
1257 | self:setFillUnitCapacity(fillUnitIndex, baleCapacity * spec.buffer.capacityPercentage, false) |
1258 | end |
1259 | end |
1260 | |
1261 | ObjectChangeUtil.setObjectChanges(baleTypeDef.changeObjects, true, self, self.setMovingToolDirty) |
1262 | |
1263 | if spec.currentBaleXMLFilename == nil then |
1264 | Logging.warning("Could not find bale for given bale type definition '%s'", baleTypeDef.index) |
1265 | end |
1266 | end |
1267 | end |
1268 | end |
onDelete
DescriptionDefinitiononDelete()Code
646 | function Baler:onDelete() |
647 | local spec = self.spec_baler |
648 | |
649 | if spec.bales ~= nil then |
650 | -- if the baler was sold we drop the bales |
651 | -- if vehicle is reconfigurated the bales are deleted with vehicle visuals |
652 | if self.isReconfigurating == nil or not self.isReconfigurating then |
653 | for k, _ in pairs(spec.bales) do |
654 | self:dropBale(k) |
655 | end |
656 | else |
657 | for _, bale in pairs(spec.bales) do |
658 | if bale.baleObject ~= nil then |
659 | bale.baleObject:delete() |
660 | end |
661 | end |
662 | end |
663 | end |
664 | |
665 | self:deleteDummyBale(spec.dummyBale) |
666 | if spec.buffer.dummyBale.available then |
667 | self:deleteDummyBale(spec.buffer.dummyBale) |
668 | end |
669 | |
670 | g_soundManager:deleteSamples(spec.samples) |
671 | g_effectManager:deleteEffects(spec.fillEffects) |
672 | g_animationManager:deleteAnimations(spec.animationNodes) |
673 | g_animationManager:deleteAnimations(spec.unloadAnimationNodes) |
674 | end |
onEndWorkAreaProcessing
DescriptionDefinitiononEndWorkAreaProcessing()Code
2182 | function Baler:onEndWorkAreaProcessing(dt, hasProcessed) |
2183 | local spec = self.spec_baler |
2184 | |
2185 | if self.isServer then |
2186 | local maxFillType = FillType.UNKNOWN |
2187 | local maxFillTypeFillLevel = 0 |
2188 | for fillTypeIndex, fillLevel in pairs(spec.pickupFillTypes) do |
2189 | if fillLevel > maxFillTypeFillLevel then |
2190 | maxFillType = fillTypeIndex |
2191 | maxFillTypeFillLevel = fillLevel |
2192 | end |
2193 | end |
2194 | |
2195 | local pickedUpLiters = spec.workAreaParameters.lastPickedUpLiters |
2196 | if pickedUpLiters > 0 then |
2197 | spec.lastAreaBiggerZero = true |
2198 | |
2199 | local deltaLevel = pickedUpLiters * spec.fillScale |
2200 | |
2201 | spec.variableSpeedLimit.pickupPerSecond = spec.variableSpeedLimit.pickupPerSecond + deltaLevel |
2202 | |
2203 | if not spec.hasUnloadingAnimation then |
2204 | -- move all bales |
2205 | local deltaTime = self:getTimeFromLevel(deltaLevel) |
2206 | self:moveBales(deltaTime) |
2207 | end |
2208 | |
2209 | local fillUnitIndex = spec.fillUnitIndex |
2210 | if spec.nonStopBaling then |
2211 | if not spec.buffer.fillMainUnitAfterOverload or not spec.buffer.unloadingStarted then |
2212 | fillUnitIndex = spec.buffer.fillUnitIndex |
2213 | else |
2214 | if self:getFillUnitFreeCapacity(spec.fillUnitIndex) <= 0 then |
2215 | fillUnitIndex = spec.buffer.fillUnitIndex |
2216 | end |
2217 | end |
2218 | end |
2219 | |
2220 | if spec.buffer.loadingStateAnimation ~= nil then |
2221 | local animTime = self:getAnimationTime(spec.buffer.loadingStateAnimation) |
2222 | if fillUnitIndex == spec.fillUnitIndex then |
2223 | if animTime >= 0.99 then |
2224 | self:playAnimation(spec.buffer.loadingStateAnimation, -spec.buffer.loadingStateAnimationSpeed) |
2225 | end |
2226 | else |
2227 | if animTime <= 0.01 then |
2228 | self:playAnimation(spec.buffer.loadingStateAnimation, spec.buffer.loadingStateAnimationSpeed) |
2229 | end |
2230 | end |
2231 | end |
2232 | |
2233 | self:setFillUnitFillType(fillUnitIndex, maxFillType) |
2234 | self:addFillUnitFillLevel(self:getOwnerFarmId(), fillUnitIndex, deltaLevel, maxFillType, ToolType.UNDEFINED) |
2235 | end |
2236 | |
2237 | if spec.lastAreaBiggerZero ~= spec.lastAreaBiggerZeroSent then |
2238 | self:raiseDirtyFlags(spec.dirtyFlag) |
2239 | spec.lastAreaBiggerZeroSent = spec.lastAreaBiggerZero |
2240 | end |
2241 | |
2242 | if spec.fillEffectType ~= spec.fillEffectTypeSent then |
2243 | spec.fillEffectTypeSent = spec.fillEffectType |
2244 | self:raiseDirtyFlags(spec.dirtyFlag) |
2245 | end |
2246 | end |
2247 | end |
onFillUnitFillLevelChanged
DescriptionDefinitiononFillUnitFillLevelChanged()Code
1272 | function Baler:onFillUnitFillLevelChanged(fillUnitIndex, fillLevelDelta, fillTypeIndex, toolType, fillPositionData, appliedDelta) |
1273 | local spec = self.spec_baler |
1274 | |
1275 | if fillUnitIndex == spec.fillUnitIndex then |
1276 | local baleTypeDef = spec.baleTypes[spec.currentBaleTypeIndex] |
1277 | |
1278 | local fillLevel = self:getFillUnitFillLevel(spec.fillUnitIndex) |
1279 | local capacity = self:getFillUnitCapacity(spec.fillUnitIndex) |
1280 | |
1281 | if self:updateDummyBale(spec.dummyBale, fillTypeIndex, fillLevel, capacity) then |
1282 | for i=1, #spec.baleTypes do |
1283 | self:setAnimationTime(spec.baleTypes[i].animations.fill, 0) |
1284 | end |
1285 | end |
1286 | |
1287 | if fillLevel > 0 then |
1288 | self:setAnimationTime(baleTypeDef.animations.fill, fillLevel / capacity) |
1289 | end |
1290 | |
1291 | -- create bale |
1292 | if self.isServer then |
1293 | if fillLevelDelta > 0 then |
1294 | if self:getFillUnitFreeCapacity(spec.fillUnitIndex) <= 0 then |
1295 | if self.isAddedToPhysics then |
1296 | self:finishBale() |
1297 | else |
1298 | -- if the baler is not added to physic (e.g. on load) we create the bale delayed, so we can mount it directly |
1299 | spec.createBaleNextFrame = true |
1300 | end |
1301 | |
1302 | spec.fillUnitOverflowFillLevel = fillLevelDelta - appliedDelta |
1303 | else |
1304 | -- fill level that is too much for the last bale will be added to the next bale (independent of the filltype) |
1305 | if spec.fillUnitOverflowFillLevel > 0 then |
1306 | if fillLevelDelta > 0 then |
1307 | local overflow = spec.fillUnitOverflowFillLevel |
1308 | spec.fillUnitOverflowFillLevel = 0 |
1309 | overflow = overflow - self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, overflow, fillTypeIndex, toolType) |
1310 | spec.fillUnitOverflowFillLevel = overflow |
1311 | end |
1312 | end |
1313 | end |
1314 | end |
1315 | end |
1316 | elseif spec.nonStopBaling and fillUnitIndex == spec.buffer.fillUnitIndex then |
1317 | if spec.buffer.dummyBale.available then |
1318 | local fillLevel = self:getFillUnitFillLevel(spec.buffer.fillUnitIndex) |
1319 | local capacity = self:getFillUnitCapacity(spec.buffer.fillUnitIndex) |
1320 | |
1321 | if spec.buffer.overloadAnimation ~= nil then |
1322 | if self:getAnimationTime(spec.buffer.overloadAnimation) > 0 and fillLevel > 0 then |
1323 | return |
1324 | end |
1325 | end |
1326 | |
1327 | self:updateDummyBale(spec.buffer.dummyBale, fillTypeIndex, fillLevel, capacity) |
1328 | end |
1329 | end |
1330 | end |
onLoad
DescriptionDefinitiononLoad()Code
236 | function Baler:onLoad(savegame) |
237 | local spec = self.spec_baler |
238 | |
239 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.fillScale#value", "vehicle.baler#fillScale") --FS15 to FS17 |
240 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.turnedOnRotationNodes.turnedOnRotationNode#type", "vehicle.baler.animationNodes.animationNode", "baler") --FS17 to FS19 |
241 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.baler.balingAnimation#name", "vehicle.turnOnVehicle.turnedOnAnimation#name") --FS17 to FS19 |
242 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.baler.fillParticleSystems", "vehicle.baler.fillEffect with effectClass 'ParticleEffect'") --FS17 to FS19 |
243 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.baler.uvScrollParts.uvScrollPart", "vehicle.baler.animationNodes.animationNode") --FS17 to FS19 |
244 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.baler.balerAlarm", "vehicle.fillUnit.fillUnitConfigurations.fillUnitConfiguration.fillUnits.fillUnit.alarmTriggers.alarmTrigger.alarmSound") --FS17 to FS19 |
245 | |
246 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.baler.baleAnimation#node", "vehicle.baler.baleTypes.baleType#baleNode") --FS19 to FS22 |
247 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.baler.baleAnimation#baleNode", "vehicle.baler.baleTypes.baleType#baleNode") --FS19 to FS22 |
248 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.baler.baleAnimation#scaleNode", "vehicle.baler.baleTypes.baleType#scaleNode") --FS19 to FS22 |
249 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.baler.baleAnimation#baleScaleComponent", "vehicle.baler.baleTypes.baleType#scaleComponents") --FS19 to FS22 |
250 | |
251 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.baler.baleAnimation#unloadAnimationName", "vehicle.baler.baleTypes.baleType#unloadAnimation") --FS19 to FS22 |
252 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.baler.baleAnimation#unloadAnimationSpeed", "vehicle.baler.baleTypes.baleType#unloadAnimationSpeed") --FS19 to FS22 |
253 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.baler.baleAnimation#baleDropAnimTime", "vehicle.baler.baleTypes.baleType#dropAnimationTime") --FS19 to FS22 |
254 | |
255 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.baler#toggleAutomaticDropTextPos", "vehicle.baler.automaticDrop#textPos") --FS19 to FS22 |
256 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.baler#toggleAutomaticDropTextNeg", "vehicle.baler.automaticDrop#textNeg") --FS19 to FS22 |
257 | |
258 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.baler.baleAnimation#firstBaleMarker", "Please adjust bale nodes to match the default balers") --FS19 to FS22 |
259 | |
260 | spec.fillScale = self.xmlFile:getValue("vehicle.baler#fillScale", 1) |
261 | spec.fillUnitIndex = self.xmlFile:getValue("vehicle.baler#fillUnitIndex", 1) |
262 | |
263 | if self.xmlFile:hasProperty("vehicle.baler.baleAnimation") then |
264 | local baleAnimCurve = AnimCurve.new(linearInterpolatorN) |
265 | |
266 | local keyframes = {} |
267 | local lastX, lastY, lastZ |
268 | local totalLength = 0 |
269 | self.xmlFile:iterate("vehicle.baler.baleAnimation.key", function(_, key) |
270 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, key .. "#time") --FS19 to FS22 |
271 | |
272 | local keyframe = {} |
273 | keyframe.x, keyframe.y, keyframe.z = self.xmlFile:getValue(key.."#pos") |
274 | keyframe.rx, keyframe.ry, keyframe.rz = self.xmlFile:getValue(key.."#rot", "0 0 0") |
275 | |
276 | if lastX ~= nil then |
277 | keyframe.length = MathUtil.vector3Length(lastX-keyframe.x, lastY-keyframe.y, lastZ-keyframe.z) |
278 | totalLength = totalLength + keyframe.length |
279 | keyframe.pos = totalLength |
280 | end |
281 | |
282 | table.insert(keyframes, keyframe) |
283 | |
284 | lastX, lastY, lastZ = keyframe.x, keyframe.y, keyframe.z |
285 | end) |
286 | |
287 | for i=1, #keyframes do |
288 | local keyframe = keyframes[i] |
289 | local t = 0 |
290 | if keyframe.pos ~= nil then |
291 | t = keyframe.pos / totalLength |
292 | end |
293 | |
294 | baleAnimCurve:addKeyframe({keyframe.x, keyframe.y, keyframe.z, keyframe.rx, keyframe.ry, keyframe.rz, time = t}) |
295 | end |
296 | |
297 | if #keyframes > 0 then |
298 | spec.baleAnimCurve = baleAnimCurve |
299 | spec.baleAnimLength = totalLength |
300 | spec.baleAnimSpacing = self.xmlFile:getValue("vehicle.baler.baleAnimation#spacing", 0) |
301 | end |
302 | end |
303 | |
304 | spec.hasUnloadingAnimation = true |
305 | |
306 | local defaultBaleTypeIndex = 1 |
307 | spec.baleTypes = {} |
308 | self.xmlFile:iterate("vehicle.baler.baleTypes.baleType", function(index, key) |
309 | if #spec.baleTypes >= BalerBaleTypeEvent.MAX_NUM_BALE_TYPES then |
310 | Logging.xmlError(self.xmlFile, "Too many bale types defined. Max. amount is '%d'! '%s'", BalerBaleTypeEvent.MAX_NUM_BALE_TYPES, key) |
311 | return false |
312 | end |
313 | |
314 | local baleTypeDefinition = {} |
315 | baleTypeDefinition.index = index |
316 | baleTypeDefinition.isRoundBale = self.xmlFile:getValue(key.."#isRoundBale", false) |
317 | baleTypeDefinition.width = MathUtil.round(self.xmlFile:getValue(key.."#width", 1.2), 2) |
318 | baleTypeDefinition.height = MathUtil.round(self.xmlFile:getValue(key.."#height", 0.9), 2) |
319 | baleTypeDefinition.length = MathUtil.round(self.xmlFile:getValue(key.."#length", 2.4), 2) |
320 | baleTypeDefinition.diameter = MathUtil.round(self.xmlFile:getValue(key.."#diameter", 1.8), 2) |
321 | |
322 | baleTypeDefinition.isDefault = self.xmlFile:getValue(key.."#isDefault", false) |
323 | if baleTypeDefinition.isDefault then |
324 | defaultBaleTypeIndex = index |
325 | end |
326 | |
327 | baleTypeDefinition.baleNode = self.xmlFile:getValue(key..".nodes#baleNode", nil, self.components, self.i3dMappings) |
328 | baleTypeDefinition.baleRootNode, baleTypeDefinition.baleNodeComponent = self.xmlFile:getValue(key..".nodes#baleRootNode", baleTypeDefinition.baleNode, self.components, self.i3dMappings) |
329 | if baleTypeDefinition.baleRootNode ~= nil and baleTypeDefinition.baleNodeComponent == nil then |
330 | baleTypeDefinition.baleNodeComponent = self:getParentComponent(baleTypeDefinition.baleRootNode) |
331 | end |
332 | |
333 | if baleTypeDefinition.baleNode ~= nil then |
334 | baleTypeDefinition.scaleNode = self.xmlFile:getValue(key..".nodes#scaleNode", nil, self.components, self.i3dMappings) |
335 | baleTypeDefinition.scaleComponents = self.xmlFile:getValue(key..".nodes#scaleComponents", nil, true) |
336 | |
337 | baleTypeDefinition.animations = {} |
338 | baleTypeDefinition.animations.fill = self.xmlFile:getValue(key..".animations#fillAnimation") |
339 | |
340 | baleTypeDefinition.animations.unloading = self.xmlFile:getValue(key..".animations#unloadAnimation") |
341 | baleTypeDefinition.animations.unloadingSpeed = self.xmlFile:getValue(key..".animations#unloadAnimationSpeed", 1) |
342 | baleTypeDefinition.animations.dropAnimationTime = self.xmlFile:getValue(key..".animations#dropAnimationTime", self:getAnimationDuration(baleTypeDefinition.animations.unloading) / 1000) |
343 | |
344 | baleTypeDefinition.detailVisibilityCutNodes = {} |
345 | self.xmlFile:iterate(key .. ".detailVisibilityCutNode", function(_, detailsVisNodeKey) |
346 | local detailVisibilityCutNode = {} |
347 | detailVisibilityCutNode.node = self.xmlFile:getValue(detailsVisNodeKey.."#node", nil, self.components, self.i3dMappings) |
348 | if detailVisibilityCutNode.node ~= nil then |
349 | detailVisibilityCutNode.axis = self.xmlFile:getValue(detailsVisNodeKey.."#axis", 3) |
350 | detailVisibilityCutNode.direction = self.xmlFile:getValue(detailsVisNodeKey.."#direction", 1) |
351 | |
352 | table.insert(baleTypeDefinition.detailVisibilityCutNodes, detailVisibilityCutNode) |
353 | end |
354 | end) |
355 | |
356 | baleTypeDefinition.changeObjects = {} |
357 | ObjectChangeUtil.loadObjectChangeFromXML(self.xmlFile, key, baleTypeDefinition.changeObjects, self.components, self) |
358 | |
359 | table.insert(spec.baleTypes, baleTypeDefinition) |
360 | |
361 | spec.hasUnloadingAnimation = spec.hasUnloadingAnimation and baleTypeDefinition.animations.unloading ~= nil |
362 | else |
363 | Logging.xmlError(self.xmlFile, "Missing baleNode for bale type. '%s'", key) |
364 | end |
365 | end) |
366 | |
367 | local defaultBaleType = spec.baleTypes[defaultBaleTypeIndex] |
368 | if defaultBaleType ~= nil then |
369 | ObjectChangeUtil.setObjectChanges(defaultBaleType.changeObjects, true, self, self.setMovingToolDirty) |
370 | end |
371 | |
372 | spec.changeBaleTypeText = self.xmlFile:getValue("vehicle.baler.baleTypes#changeText", "action_changeBaleSize", self.customEnvironment) |
373 | |
374 | spec.preSelectedBaleTypeIndex = defaultBaleTypeIndex |
375 | spec.currentBaleTypeIndex = defaultBaleTypeIndex |
376 | spec.currentBaleXMLFilename = nil |
377 | spec.currentBaleTypeDefinition = nil |
378 | |
379 | if #spec.baleTypes == 0 then |
380 | Logging.xmlError(self.xmlFile, "No baleTypes definded for baler.") |
381 | end |
382 | |
383 | if spec.hasUnloadingAnimation then |
384 | spec.automaticDrop = self.xmlFile:getValue("vehicle.baler.automaticDrop#enabled", Platform.gameplay.automaticBaleDrop) |
385 | spec.toggleableAutomaticDrop = self.xmlFile:getValue("vehicle.baler.automaticDrop#toggleable", not Platform.gameplay.automaticBaleDrop) |
386 | |
387 | spec.toggleAutomaticDropTextPos = self.xmlFile:getValue("vehicle.baler.automaticDrop#textPos", "action_toggleAutomaticBaleDropPos", self.customEnvironment) |
388 | spec.toggleAutomaticDropTextNeg = self.xmlFile:getValue("vehicle.baler.automaticDrop#textNeg", "action_toggleAutomaticBaleDropNeg", self.customEnvironment) |
389 | |
390 | spec.baleCloseAnimationName = self.xmlFile:getValue("vehicle.baler.baleAnimation#closeAnimationName") |
391 | spec.baleCloseAnimationSpeed = self.xmlFile:getValue("vehicle.baler.baleAnimation#closeAnimationSpeed", 1) |
392 | |
393 | local closeAnimation = self:getAnimationByName(spec.baleCloseAnimationName) |
394 | if spec.baleCloseAnimationName == nil or closeAnimation == nil then |
395 | Logging.xmlError(self.xmlFile, "Failed to find baler close animation. (%s)", "vehicle.baler.baleAnimation#closeAnimationName") |
396 | else |
397 | closeAnimation.resetOnStart = false |
398 | end |
399 | end |
400 | |
401 | spec.unfinishedBaleThreshold = self.xmlFile:getValue("vehicle.baler#unfinishedBaleThreshold", 2000) |
402 | spec.canUnloadUnfinishedBale = self.xmlFile:getValue("vehicle.baler#canUnloadUnfinishedBale", false) |
403 | spec.lastBaleFillLevel = nil |
404 | |
405 | if self.isClient then |
406 | spec.samples = {} |
407 | spec.samples.work = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.baler.sounds", "work", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
408 | spec.samples.eject = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.baler.sounds", "eject", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
409 | spec.samples.unload = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.baler.sounds", "unload", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
410 | spec.samples.door = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.baler.sounds", "door", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) |
411 | spec.samples.knotCleaning = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.baler.sounds", "knotCleaning", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) |
412 | |
413 | spec.knotCleaningTimer = 10000 |
414 | spec.knotCleaningTime = 120000 |
415 | |
416 | spec.animationNodes = g_animationManager:loadAnimations(self.xmlFile, "vehicle.baler.animationNodes", self.components, self, self.i3dMappings) |
417 | spec.unloadAnimationNodes = g_animationManager:loadAnimations(self.xmlFile, "vehicle.baler.unloadAnimationNodes", self.components, self, self.i3dMappings) |
418 | spec.fillEffects = g_effectManager:loadEffect(self.xmlFile, "vehicle.baler.fillEffect", self.components, self, self.i3dMappings) |
419 | spec.fillEffectType = FillType.UNKNOWN |
420 | |
421 | spec.knotingAnimation = self.xmlFile:getValue("vehicle.baler.knotingAnimation#name") |
422 | spec.knotingAnimationSpeed = self.xmlFile:getValue("vehicle.baler.knotingAnimation#speed", 1) |
423 | |
424 | spec.compactingAnimation = self.xmlFile:getValue("vehicle.baler.compactingAnimation#name") |
425 | spec.compactingAnimationInterval = self.xmlFile:getValue("vehicle.baler.compactingAnimation#interval", 60) * 1000 |
426 | spec.compactingAnimationCompactTime = self.xmlFile:getValue("vehicle.baler.compactingAnimation#compactTime", 5) * 1000 |
427 | spec.compactingAnimationCompactTimer = spec.compactingAnimationCompactTime |
428 | spec.compactingAnimationTime = spec.compactingAnimationInterval |
429 | spec.compactingAnimationSpeed = self.xmlFile:getValue("vehicle.baler.compactingAnimation#speed", 1) |
430 | spec.compactingAnimationMinTime = self.xmlFile:getValue("vehicle.baler.compactingAnimation#minFillLevelTime", 1) |
431 | spec.compactingAnimationMaxTime = self.xmlFile:getValue("vehicle.baler.compactingAnimation#maxFillLevelTime", 0.1) |
432 | end |
433 | |
434 | spec.lastAreaBiggerZero = false |
435 | spec.lastAreaBiggerZeroSent = false |
436 | spec.lastAreaBiggerZeroTime = 0 |
437 | |
438 | spec.workAreaParameters = {} |
439 | spec.workAreaParameters.lastPickedUpLiters = 0 |
440 | |
441 | spec.fillUnitOverflowFillLevel = 0 |
442 | |
443 | spec.maxPickupLitersPerSecond = self.xmlFile:getValue("vehicle.baler#maxPickupLitersPerSecond", 500) |
444 | spec.pickUpLitersBuffer = ValueBuffer.new(750) |
445 | |
446 | spec.unloadingState = Baler.UNLOADING_CLOSED |
447 | spec.pickupFillTypes = {} |
448 | |
449 | spec.bales = {} |
450 | |
451 | spec.dummyBale = {} |
452 | spec.dummyBale.currentBaleFillType = FillType.UNKNOWN |
453 | spec.dummyBale.currentBale = nil |
454 | spec.dummyBale.currentBaleLength = 0 |
455 | |
456 | spec.allowsBaleUnloading = self.xmlFile:getValue("vehicle.baler.baleUnloading#allowed", false) |
457 | spec.baleUnloadingTime = self.xmlFile:getValue("vehicle.baler.baleUnloading#time", 4) * 1000 |
458 | spec.baleFoldThreshold = self.xmlFile:getValue("vehicle.baler.baleUnloading#foldThreshold", 0.25) * self:getFillUnitCapacity(spec.fillUnitIndex) |
459 | |
460 | spec.platformAnimation = self.xmlFile:getValue("vehicle.baler.platform#animationName") |
461 | spec.platformAnimationNextBaleTime = self.xmlFile:getValue("vehicle.baler.platform#nextBaleTime", 0) |
462 | spec.platformAutomaticDrop = self.xmlFile:getValue("vehicle.baler.platform#automaticDrop", Platform.gameplay.automaticBaleDrop) |
463 | spec.platformAIDropSpeed = self.xmlFile:getValue("vehicle.baler.platform#aiSpeed", 3) |
464 | |
465 | spec.hasPlatform = spec.platformAnimation ~= nil |
466 | spec.hasDynamicMountPlatform = SpecializationUtil.hasSpecialization(DynamicMountAttacher, self.specializations) |
467 | |
468 | -- always automatically drop bale to platform, but player can decide when to drop from platform |
469 | if spec.hasPlatform then |
470 | spec.automaticDrop = true |
471 | end |
472 | |
473 | spec.platformReadyToDrop = false -- bale is on platform and ready to be dropped |
474 | spec.platformDropInProgress = false -- bale is currently dropping from platform |
475 | spec.platformDelayedDropping = false -- unload baler if bale was dropped from platform |
476 | spec.platformMountDelay = -1 -- when counter reaches zero the bale in the platform trigger is forced to be mounted |
477 | |
478 | spec.buffer = {} |
479 | spec.buffer.fillUnitIndex = self.xmlFile:getValue("vehicle.baler.buffer#fillUnitIndex") |
480 | spec.buffer.capacityPercentage = self.xmlFile:getValue("vehicle.baler.buffer#capacityPercentage") |
481 | spec.buffer.overloadingDuration = self.xmlFile:getValue("vehicle.baler.buffer#overloadingDuration", 1) |
482 | spec.buffer.fillMainUnitAfterOverload = self.xmlFile:getValue("vehicle.baler.buffer#fillMainUnitAfterOverload", false) |
483 | spec.buffer.unloadingStarted = false |
484 | spec.buffer.fillLevelToEmpty = 0 |
485 | |
486 | spec.buffer.dummyBale = {} |
487 | spec.buffer.dummyBale.available = self.xmlFile:hasProperty("vehicle.baler.buffer.dummyBale") |
488 | spec.buffer.dummyBale.linkNode = self.xmlFile:getValue("vehicle.baler.buffer.dummyBale#node", nil, self.components, self.i3dMappings) |
489 | spec.buffer.dummyBale.scaleComponents = self.xmlFile:getValue("vehicle.baler.buffer.dummyBale#scaleComponents", "1 1 0", true) |
490 | |
491 | spec.buffer.overloadAnimation = self.xmlFile:getValue("vehicle.baler.buffer.overloadAnimation#name") |
492 | spec.buffer.overloadAnimationSpeed = self.xmlFile:getValue("vehicle.baler.buffer.overloadAnimation#speedScale", 1) |
493 | |
494 | spec.buffer.loadingStateAnimation = self.xmlFile:getValue("vehicle.baler.buffer.loadingStateAnimation#name") |
495 | spec.buffer.loadingStateAnimationSpeed = self.xmlFile:getValue("vehicle.baler.buffer.loadingStateAnimation#speedScale", 1) |
496 | |
497 | spec.nonStopBaling = spec.buffer.fillUnitIndex ~= nil |
498 | |
499 | if spec.nonStopBaling ~= nil then |
500 | local fillTypeName = self.xmlFile:getValue("vehicle.baler.buffer#balerDisplayType") |
501 | local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(fillTypeName) |
502 | if fillTypeIndex ~= nil then |
503 | self:setFillUnitFillTypeToDisplay(spec.fillUnitIndex, fillTypeIndex, true) |
504 | end |
505 | end |
506 | |
507 | spec.variableSpeedLimit = {} |
508 | spec.variableSpeedLimit.enabled = self.xmlFile:hasProperty("vehicle.baler.variableSpeedLimit") |
509 | spec.variableSpeedLimit.pickupPerSecond = 0 |
510 | spec.variableSpeedLimit.pickupPerSecondTimer = 0 |
511 | spec.variableSpeedLimit.targetLiterPerSecond = self.xmlFile:getValue("vehicle.baler.variableSpeedLimit#targetLiterPerSecond", 200) |
512 | spec.variableSpeedLimit.changeInterval = self.xmlFile:getValue("vehicle.baler.variableSpeedLimit#changeInterval", 1) |
513 | spec.variableSpeedLimit.minSpeedLimit = self.xmlFile:getValue("vehicle.baler.variableSpeedLimit#minSpeedLimit", 5) |
514 | spec.variableSpeedLimit.maxSpeedLimit = self.xmlFile:getValue("vehicle.baler.variableSpeedLimit#maxSpeedLimit", 15) |
515 | spec.variableSpeedLimit.defaultSpeedLimit = self.xmlFile:getValue("vehicle.baler.variableSpeedLimit#defaultSpeedLimit", 10) |
516 | spec.variableSpeedLimit.backupSpeedLimit = self.speedLimit |
517 | spec.variableSpeedLimit.usedBackupSpeedLimit = false |
518 | spec.variableSpeedLimit.lastAdjustedSpeedLimit = nil |
519 | spec.variableSpeedLimit.lastAdjustedSpeedLimitType = nil |
520 | |
521 | spec.variableSpeedLimit.fillTypeToTargetLiterPerSecond = {} |
522 | |
523 | self.xmlFile:iterate("vehicle.baler.variableSpeedLimit.target", function(index, key) |
524 | local fillType = g_fillTypeManager:getFillTypeIndexByName(self.xmlFile:getValue(key .. "#fillType")) |
525 | if fillType ~= nil then |
526 | local targetLiterPerSecond = self.xmlFile:getValue(key .. "#targetLiterPerSecond", 200) |
527 | local defaultSpeedLimit = self.xmlFile:getValue(key .. "#defaultSpeedLimit", 10) |
528 | spec.variableSpeedLimit.fillTypeToTargetLiterPerSecond[fillType] = {targetLiterPerSecond=targetLiterPerSecond, defaultSpeedLimit=defaultSpeedLimit} |
529 | end |
530 | end) |
531 | |
532 | spec.additives = {} |
533 | spec.additives.fillUnitIndex = self.xmlFile:getValue("vehicle.baler.additives#fillUnitIndex") |
534 | spec.additives.available = self:getFillUnitByIndex(spec.additives.fillUnitIndex) ~= nil |
535 | spec.additives.usage = self.xmlFile:getValue("vehicle.baler.additives#usage", 0.0000275) |
536 | local additivesFillTypeNames = self.xmlFile:getValue("vehicle.baler.additives#fillTypes", "GRASS_WINDROW") |
537 | spec.additives.fillTypes = g_fillTypeManager:getFillTypesByNames(additivesFillTypeNames, "Warning: '"..self.xmlFile:getFilename().. "' has invalid fillType '%s'.") |
538 | |
539 | spec.isBaleUnloading = false |
540 | |
541 | spec.texts = {} |
542 | spec.texts.warningFoldingBaleLoaded = g_i18n:getText("warning_foldingNotWhileBaleLoaded") |
543 | spec.texts.warningFoldingTurnedOn = g_i18n:getText("warning_foldingNotWhileTurnedOn") |
544 | spec.texts.warningTooManyBales = g_i18n:getText("warning_tooManyBales") |
545 | spec.texts.unloadUnfinishedBale = g_i18n:getText("action_unloadUnfinishedBale") |
546 | spec.texts.unloadBaler = g_i18n:getText("action_unloadBaler") |
547 | spec.texts.closeBack = g_i18n:getText("action_closeBack") |
548 | |
549 | spec.showBaleLimitWarning = false |
550 | |
551 | spec.dirtyFlag = self:getNextDirtyFlag() |
552 | |
553 | -- set already here to be set before the fill units are loaded and we may get a different first bale |
554 | if savegame ~= nil and not savegame.resetVehicles then |
555 | local baleTypeIndex = savegame.xmlFile:getValue(savegame.key..".baler#baleTypeIndex", spec.currentBaleTypeIndex) |
556 | self:setBaleTypeIndex(baleTypeIndex, true, true) |
557 | |
558 | local preSelectedBaleTypeIndex = savegame.xmlFile:getValue(savegame.key..".baler#preSelectedBaleTypeIndex", spec.preSelectedBaleTypeIndex) |
559 | self:setBaleTypeIndex(preSelectedBaleTypeIndex, nil, true) |
560 | |
561 | local fillUnitCapacity = savegame.xmlFile:getValue(savegame.key .. ".baler#fillUnitCapacity") |
562 | if fillUnitCapacity ~= nil then |
563 | if fillUnitCapacity == 0 then |
564 | fillUnitCapacity = math.huge |
565 | end |
566 | |
567 | self:setFillUnitCapacity(spec.fillUnitIndex, fillUnitCapacity) |
568 | |
569 | if spec.buffer.capacityPercentage ~= nil then |
570 | self:setFillUnitCapacity(spec.fillUnitIndex, fillUnitCapacity * spec.buffer.capacityPercentage, false) |
571 | end |
572 | end |
573 | |
574 | if spec.nonStopBaling then |
575 | spec.buffer.unloadingStarted = savegame.xmlFile:getValue(savegame.key .. ".baler#bufferUnloadingStarted", spec.buffer.unloadingStarted) |
576 | end |
577 | end |
578 | end |
onLoadFinished
DescriptionDefinitiononLoadFinished()Code
624 | function Baler:onLoadFinished(savegame) |
625 | local spec = self.spec_baler |
626 | if self.isServer then |
627 | if spec.createBaleNextFrame ~= nil and spec.createBaleNextFrame then |
628 | self:finishBale() |
629 | spec.createBaleNextFrame = nil |
630 | end |
631 | end |
632 | |
633 | if spec.balesToLoad ~= nil then |
634 | for _, v in ipairs(spec.balesToLoad) do |
635 | if self:createBale(v.fillType, v.fillLevel, nil, v.baleTime, v.filename) then |
636 | self:setBaleTime(#spec.bales, v.baleTime, true) |
637 | end |
638 | end |
639 | |
640 | spec.balesToLoad = nil |
641 | end |
642 | end |
onPostLoad
DescriptionDefinitiononPostLoad()Code
582 | function Baler:onPostLoad(savegame) |
583 | local spec = self.spec_baler |
584 | |
585 | for fillTypeIndex, enabled in pairs(self:getFillUnitSupportedFillTypes(spec.fillUnitIndex)) do |
586 | if enabled and fillTypeIndex ~= FillType.UNKNOWN then |
587 | spec.pickupFillTypes[fillTypeIndex] = 0 |
588 | end |
589 | end |
590 | |
591 | if savegame ~= nil and not savegame.resetVehicles then |
592 | local numBales = savegame.xmlFile:getValue(savegame.key..".baler#numBales") |
593 | if numBales ~= nil then |
594 | spec.balesToLoad = {} |
595 | for i=1, numBales do |
596 | local baleKey = string.format("%s.baler.bale(%d)", savegame.key, i-1) |
597 | local bale = {} |
598 | local filename = savegame.xmlFile:getValue(baleKey.."#filename") |
599 | local fillTypeStr = savegame.xmlFile:getValue(baleKey.."#fillType") |
600 | local fillType = g_fillTypeManager:getFillTypeByName(fillTypeStr) |
601 | if filename ~= nil and fillType ~= nil then |
602 | bale.filename = filename |
603 | bale.fillType = fillType.index |
604 | bale.fillLevel = savegame.xmlFile:getValue(baleKey.."#fillLevel") |
605 | bale.baleTime = savegame.xmlFile:getValue(baleKey.."#baleTime") |
606 | table.insert(spec.balesToLoad, bale) |
607 | end |
608 | end |
609 | end |
610 | |
611 | if spec.hasPlatform then |
612 | spec.platformReadyToDrop = savegame.xmlFile:getValue(savegame.key .. ".baler#platformReadyToDrop", spec.platformReadyToDrop) |
613 | if spec.platformReadyToDrop then |
614 | self:setAnimationTime(spec.platformAnimation, 1, true) |
615 | self:setAnimationTime(spec.platformAnimation, 0, true) |
616 | spec.platformMountDelay = 1 |
617 | end |
618 | end |
619 | end |
620 | end |
onReadStream
DescriptionDefinitiononReadStream()Code
718 | function Baler:onReadStream(streamId, connection) |
719 | local spec = self.spec_baler |
720 | |
721 | if spec.hasUnloadingAnimation then |
722 | local state = streamReadUIntN(streamId, 7) |
723 | local animTime = streamReadFloat32(streamId) |
724 | if state == Baler.UNLOADING_CLOSED or state == Baler.UNLOADING_CLOSING then |
725 | self:setIsUnloadingBale(false, true) |
726 | self:setRealAnimationTime(spec.baleCloseAnimationName, animTime) |
727 | elseif state == Baler.UNLOADING_OPEN or state == Baler.UNLOADING_OPENING then |
728 | self:setIsUnloadingBale(true, true) |
729 | self:setRealAnimationTime(spec.baleUnloadAnimationName, animTime) |
730 | end |
731 | end |
732 | |
733 | local numBales = streamReadUInt8(streamId) |
734 | for i=1, numBales do |
735 | local fillType = streamReadIntN(streamId, FillTypeManager.SEND_NUM_BITS) |
736 | local fillLevel = streamReadFloat32(streamId) |
737 | self:createBale(fillType, fillLevel) |
738 | if spec.baleAnimCurve ~= nil then |
739 | local baleTime = streamReadFloat32(streamId) |
740 | self:setBaleTime(i, baleTime) |
741 | end |
742 | end |
743 | |
744 | spec.lastAreaBiggerZero = streamReadBool(streamId) |
745 | |
746 | if spec.hasPlatform then |
747 | spec.platformReadyToDrop = streamReadBool(streamId) |
748 | if spec.platformReadyToDrop then |
749 | self:setAnimationTime(spec.platformAnimation, 1, true) |
750 | self:setAnimationTime(spec.platformAnimation, 0, true) |
751 | end |
752 | end |
753 | |
754 | spec.currentBaleTypeIndex = streamReadUIntN(streamId, BalerBaleTypeEvent.BALE_TYPE_SEND_NUM_BITS) |
755 | spec.preSelectedBaleTypeIndex = streamReadUIntN(streamId, BalerBaleTypeEvent.BALE_TYPE_SEND_NUM_BITS) |
756 | |
757 | local capacity = streamReadFloat32(streamId) |
758 | self:setFillUnitCapacity(spec.fillUnitIndex, capacity) |
759 | |
760 | local fillLevel = streamReadFloat32(streamId) |
761 | local fillUnit = self:getFillUnitByIndex(spec.fillUnitIndex) |
762 | if fillUnit ~= nil then |
763 | fillUnit.fillLevel = fillLevel |
764 | end |
765 | end |
onReadUpdateStream
DescriptionDefinitiononReadUpdateStream()Code
808 | function Baler:onReadUpdateStream(streamId, timestamp, connection) |
809 | local spec = self.spec_baler |
810 | |
811 | if connection:getIsServer() then |
812 | if streamReadBool(streamId) then |
813 | spec.lastAreaBiggerZero = streamReadBool(streamId) |
814 | spec.fillEffectType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS) |
815 | spec.showBaleLimitWarning = streamReadBool(streamId) |
816 | end |
817 | end |
818 | end |
onRegisterActionEvents
DescriptionDefinitiononRegisterActionEvents()Code
2137 | function Baler:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection) |
2138 | if self.isClient then |
2139 | local spec = self.spec_baler |
2140 | self:clearActionEventsTable(spec.actionEvents) |
2141 | |
2142 | if isActiveForInputIgnoreSelection then |
2143 | if not spec.automaticDrop or not spec.platformAutomaticDrop then |
2144 | local _, actionEventId = self:addPoweredActionEvent(spec.actionEvents, InputAction.IMPLEMENT_EXTRA3, self, Baler.actionEventUnloading, false, true, false, true, nil) |
2145 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_HIGH) |
2146 | end |
2147 | |
2148 | if #spec.baleTypes > 1 then |
2149 | local _, actionEventId = self:addPoweredActionEvent(spec.actionEvents, InputAction.TOGGLE_BALE_TYPES, self, Baler.actionEventToggleSize, false, true, false, true, nil) |
2150 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_HIGH) |
2151 | end |
2152 | |
2153 | if spec.toggleableAutomaticDrop then |
2154 | local _, actionEventId = self:addPoweredActionEvent(spec.actionEvents, InputAction.IMPLEMENT_EXTRA4, self, Baler.actionEventToggleAutomaticDrop, false, true, false, true, nil) |
2155 | |
2156 | local automaticDropState = spec.automaticDrop |
2157 | if spec.hasPlatform then |
2158 | automaticDropState = spec.platformAutomaticDrop |
2159 | end |
2160 | g_inputBinding:setActionEventText(actionEventId, automaticDropState and spec.toggleAutomaticDropTextNeg or spec.toggleAutomaticDropTextPos) |
2161 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_HIGH) |
2162 | end |
2163 | |
2164 | Baler.updateActionEvents(self) |
2165 | end |
2166 | end |
2167 | end |
onRootVehicleChanged
DescriptionCalled if root vehicle changesDefinition
onRootVehicleChanged(table rootVehicle)Arguments
table | rootVehicle | root vehicle |
1359 | function Baler:onRootVehicleChanged(rootVehicle) |
1360 | local spec = self.spec_baler |
1361 | local actionController = rootVehicle.actionController |
1362 | if actionController ~= nil then |
1363 | if spec.controlledAction ~= nil then |
1364 | spec.controlledAction:updateParent(actionController) |
1365 | return |
1366 | end |
1367 | |
1368 | spec.controlledAction = actionController:registerAction("baleUnload", nil, 1) |
1369 | spec.controlledAction:setCallback(self, Baler.actionControllerBaleUnloadEvent) |
1370 | spec.controlledAction:setFinishedFunctions(self, Baler.getIsBaleUnloading, false, false) |
1371 | else |
1372 | if spec.controlledAction ~= nil then |
1373 | spec.controlledAction:remove() |
1374 | end |
1375 | end |
1376 | end |
onStartWorkAreaProcessing
DescriptionDefinitiononStartWorkAreaProcessing()Code
2171 | function Baler:onStartWorkAreaProcessing(dt) |
2172 | local spec = self.spec_baler |
2173 | |
2174 | if self.isServer then |
2175 | spec.lastAreaBiggerZero = false |
2176 | spec.workAreaParameters.lastPickedUpLiters = 0 |
2177 | end |
2178 | end |
onTurnedOff
DescriptionDefinitiononTurnedOff()Code
1347 | function Baler:onTurnedOff() |
1348 | if self.isClient then |
1349 | local spec = self.spec_baler |
1350 | g_effectManager:stopEffects(spec.fillEffects) |
1351 | g_animationManager:stopAnimations(spec.animationNodes) |
1352 | g_soundManager:stopSamples(spec.samples) |
1353 | end |
1354 | end |
onTurnedOn
DescriptionDefinitiononTurnedOn()Code
1334 | function Baler:onTurnedOn() |
1335 | if self.setFoldState ~= nil then |
1336 | self:setFoldState(-1, false) |
1337 | end |
1338 | if self.isClient then |
1339 | local spec = self.spec_baler |
1340 | g_animationManager:startAnimations(spec.animationNodes) |
1341 | g_soundManager:playSample(spec.samples.work) |
1342 | end |
1343 | end |
onUpdate
DescriptionDefinitiononUpdate()Code
836 | function Baler:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
837 | local spec = self.spec_baler |
838 | |
839 | if self.isClient then |
840 | if spec.baleToMount ~= nil then |
841 | local baleObject = NetworkUtil.getObject(spec.baleToMount.baleServerId) |
842 | if baleObject ~= nil then |
843 | baleObject:mountKinematic(self, spec.baleToMount.jointNode, 0, 0, 0, 0, 0, 0) |
844 | spec.baleToMount.baleInfo.baleObject = baleObject |
845 | spec.baleToMount.baleInfo.baleServerId = spec.baleToMount.baleServerId |
846 | spec.baleToMount = nil |
847 | end |
848 | end |
849 | |
850 | local baleTypeDef = spec.baleTypes[spec.currentBaleTypeIndex] |
851 | if baleTypeDef ~= nil and #baleTypeDef.detailVisibilityCutNodes > 0 then |
852 | for i=1, #spec.bales do |
853 | local bale = spec.bales[i] |
854 | if bale.baleObject ~= nil then |
855 | bale.baleObject:resetDetailVisibilityCut() |
856 | if bale.time < 1 then |
857 | for j=1, #baleTypeDef.detailVisibilityCutNodes do |
858 | local detailVisibilityCutNode = baleTypeDef.detailVisibilityCutNodes[j] |
859 | bale.baleObject:setDetailVisibilityCutNode(detailVisibilityCutNode.node, detailVisibilityCutNode.axis, detailVisibilityCutNode.direction) |
860 | end |
861 | end |
862 | end |
863 | end |
864 | |
865 | if spec.dummyBale.currentBale ~= nil then |
866 | for j=1, #baleTypeDef.detailVisibilityCutNodes do |
867 | local detailVisibilityCutNode = baleTypeDef.detailVisibilityCutNodes[j] |
868 | Bale.setBaleMeshVisibilityCut(spec.dummyBale.currentBale, detailVisibilityCutNode.node, detailVisibilityCutNode.axis, detailVisibilityCutNode.direction, true) |
869 | end |
870 | end |
871 | end |
872 | end |
873 | |
874 | if self.isServer then |
875 | if self.isAddedToPhysics then |
876 | if spec.createBaleNextFrame ~= nil and spec.createBaleNextFrame then |
877 | self:finishBale() |
878 | spec.createBaleNextFrame = nil |
879 | end |
880 | end |
881 | |
882 | -- update variable speed limit based on current pickup |
883 | if spec.variableSpeedLimit.enabled then |
884 | spec.variableSpeedLimit.pickupPerSecondTimer = spec.variableSpeedLimit.pickupPerSecondTimer + dt |
885 | if spec.variableSpeedLimit.pickupPerSecondTimer > spec.variableSpeedLimit.changeInterval then |
886 | local defaultSpeedLimit = spec.variableSpeedLimit.defaultSpeedLimit |
887 | local targetLiterPerSecond = spec.variableSpeedLimit.targetLiterPerSecond |
888 | |
889 | local fillTypeIndex = self:getFillUnitFillType(spec.fillUnitIndex) |
890 | if fillTypeIndex == FillType.UNKNOWN and spec.nonStopBaling then |
891 | fillTypeIndex = self:getFillUnitFillType(spec.buffer.fillUnitIndex) |
892 | end |
893 | if fillTypeIndex ~= nil and spec.variableSpeedLimit.fillTypeToTargetLiterPerSecond[fillTypeIndex] ~= nil then |
894 | local target = spec.variableSpeedLimit.fillTypeToTargetLiterPerSecond[fillTypeIndex] |
895 | defaultSpeedLimit = target.defaultSpeedLimit |
896 | targetLiterPerSecond = target.targetLiterPerSecond |
897 | end |
898 | |
899 | local litersPerSecond = spec.variableSpeedLimit.pickupPerSecond / (spec.variableSpeedLimit.changeInterval / 1000) |
900 | if litersPerSecond > 0 then |
901 | if spec.variableSpeedLimit.usedBackupSpeedLimit then |
902 | spec.variableSpeedLimit.usedBackupSpeedLimit = false |
903 | self.speedLimit = spec.variableSpeedLimit.lastAdjustedSpeedLimit or defaultSpeedLimit |
904 | if (spec.variableSpeedLimit.lastAdjustedSpeedLimitType or fillTypeIndex) ~= fillTypeIndex then |
905 | self.speedLimit = defaultSpeedLimit |
906 | end |
907 | end |
908 | |
909 | local threshold = targetLiterPerSecond * 0.15 |
910 | local changeAmount = math.max(math.floor((litersPerSecond * 2) / targetLiterPerSecond), 1) |
911 | if litersPerSecond > targetLiterPerSecond + threshold then |
912 | self.speedLimit = math.max(self.speedLimit - changeAmount, spec.variableSpeedLimit.minSpeedLimit) |
913 | elseif litersPerSecond < targetLiterPerSecond - threshold then |
914 | self.speedLimit = math.min(self.speedLimit + changeAmount, spec.variableSpeedLimit.maxSpeedLimit) |
915 | end |
916 | |
917 | spec.variableSpeedLimit.lastAdjustedSpeedLimit = self.speedLimit |
918 | spec.variableSpeedLimit.lastAdjustedSpeedLimitType = fillTypeIndex |
919 | else |
920 | spec.variableSpeedLimit.usedBackupSpeedLimit = true |
921 | self.speedLimit = spec.variableSpeedLimit.backupSpeedLimit |
922 | end |
923 | |
924 | spec.variableSpeedLimit.pickupPerSecondTimer = 0 |
925 | spec.variableSpeedLimit.pickupPerSecond = 0 |
926 | end |
927 | end |
928 | end |
929 | end |
onUpdateTick
DescriptionDefinitiononUpdateTick()Code
933 | function Baler:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
934 | local spec = self.spec_baler |
935 | |
936 | local showBaleLimitWarning = false |
937 | |
938 | if self:getIsTurnedOn() then |
939 | if not g_currentMission.slotSystem:getCanAddLimitedObjects(SlotSystem.LIMITED_OBJECT_BALE, 1) then |
940 | showBaleLimitWarning = true |
941 | end |
942 | |
943 | if self.isClient then |
944 | |
945 | if spec.lastAreaBiggerZero and spec.fillEffectType ~= FillType.UNKNOWN then |
946 | spec.lastAreaBiggerZeroTime = 500 |
947 | elseif spec.lastAreaBiggerZeroTime > 0 then |
948 | spec.lastAreaBiggerZeroTime = math.max(spec.lastAreaBiggerZeroTime - dt, 0) |
949 | end |
950 | |
951 | if spec.lastAreaBiggerZeroTime > 0 then |
952 | if spec.fillEffectType ~= FillType.UNKNOWN then |
953 | g_effectManager:setFillType(spec.fillEffects, spec.fillEffectType) |
954 | end |
955 | |
956 | g_effectManager:startEffects(spec.fillEffects) |
957 | |
958 | local loadPercentage = spec.pickUpLitersBuffer:get(1000) / spec.maxPickupLitersPerSecond |
959 | g_effectManager:setDensity(spec.fillEffects, math.max(loadPercentage, 0.40)) |
960 | else |
961 | g_effectManager:stopEffects(spec.fillEffects) |
962 | end |
963 | |
964 | if spec.knotCleaningTimer <= g_currentMission.time then |
965 | g_soundManager:playSample(spec.samples.knotCleaning) |
966 | spec.knotCleaningTimer = g_currentMission.time + spec.knotCleaningTime |
967 | end |
968 | |
969 | if spec.compactingAnimation ~= nil and spec.unloadingState == Baler.UNLOADING_CLOSED then |
970 | if spec.compactingAnimationTime <= g_currentMission.time then |
971 | local fillLevel = self:getFillUnitFillLevelPercentage(spec.fillUnitIndex) |
972 | local stopTime = MathUtil.lerp(spec.compactingAnimationMinTime, spec.compactingAnimationMaxTime, fillLevel) |
973 | if stopTime > 0 then |
974 | self:setAnimationStopTime(spec.compactingAnimation, MathUtil.clamp(stopTime, 0, 1)) |
975 | self:playAnimation(spec.compactingAnimation, spec.compactingAnimationSpeed, self:getAnimationTime(spec.compactingAnimation), false) |
976 | spec.compactingAnimationTime = math.huge |
977 | end |
978 | end |
979 | |
980 | if spec.compactingAnimationTime == math.huge then |
981 | if not self:getIsAnimationPlaying(spec.compactingAnimation) then |
982 | spec.compactingAnimationCompactTimer = spec.compactingAnimationCompactTimer - dt |
983 | if spec.compactingAnimationCompactTimer < 0 then |
984 | self:playAnimation(spec.compactingAnimation, -spec.compactingAnimationSpeed, self:getAnimationTime(spec.compactingAnimation), false) |
985 | spec.compactingAnimationCompactTimer = spec.compactingAnimationCompactTime |
986 | end |
987 | |
988 | if self:getAnimationTime(spec.compactingAnimation) == 0 then |
989 | spec.compactingAnimationTime = g_currentMission.time + spec.compactingAnimationInterval |
990 | end |
991 | end |
992 | end |
993 | end |
994 | end |
995 | else |
996 | if spec.isBaleUnloading and self.isServer then |
997 | local deltaTime = dt / spec.baleUnloadingTime |
998 | self:moveBales(deltaTime) |
999 | end |
1000 | end |
1001 | |
1002 | if self.isClient then |
1003 | --delete dummy bale on client after physical bale is displayed |
1004 | if spec.unloadingState == Baler.UNLOADING_OPEN then |
1005 | local baleTypeDef = spec.baleTypes[spec.currentBaleTypeIndex] |
1006 | if getNumOfChildren(baleTypeDef.baleNode) > 0 then |
1007 | delete(getChildAt(baleTypeDef.baleNode, 0)) |
1008 | end |
1009 | end |
1010 | end |
1011 | |
1012 | if spec.unloadingState == Baler.UNLOADING_OPENING then |
1013 | local baleTypeDef = spec.baleTypes[spec.currentBaleTypeIndex] |
1014 | local isPlaying = self:getIsAnimationPlaying(baleTypeDef.animations.unloading) |
1015 | local animTime = self:getRealAnimationTime(baleTypeDef.animations.unloading) |
1016 | if not isPlaying or animTime >= baleTypeDef.animations.dropAnimationTime then |
1017 | if #spec.bales > 0 then |
1018 | self:dropBale(1) |
1019 | if self.isServer then |
1020 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, -math.huge, self:getFillUnitFillType(spec.fillUnitIndex), ToolType.UNDEFINED) |
1021 | spec.buffer.unloadingStarted = false |
1022 | |
1023 | for fillType, _ in pairs(spec.pickupFillTypes) do |
1024 | spec.pickupFillTypes[fillType] = 0 |
1025 | end |
1026 | |
1027 | if self:getFillUnitFillLevel(spec.fillUnitIndex) == 0 then |
1028 | if spec.preSelectedBaleTypeIndex ~= spec.currentBaleTypeIndex then |
1029 | self:setBaleTypeIndex(spec.preSelectedBaleTypeIndex, true) |
1030 | end |
1031 | end |
1032 | end |
1033 | end |
1034 | if not isPlaying then |
1035 | spec.unloadingState = Baler.UNLOADING_OPEN |
1036 | |
1037 | if self.isClient then |
1038 | g_soundManager:stopSample(spec.samples.eject) |
1039 | g_soundManager:stopSample(spec.samples.door) |
1040 | g_animationManager:stopAnimations(spec.unloadAnimationNodes) |
1041 | end |
1042 | end |
1043 | else |
1044 | g_animationManager:startAnimations(spec.unloadAnimationNodes) |
1045 | end |
1046 | elseif spec.unloadingState == Baler.UNLOADING_CLOSING then |
1047 | if not self:getIsAnimationPlaying(spec.baleCloseAnimationName) then |
1048 | spec.unloadingState = Baler.UNLOADING_CLOSED |
1049 | if self.isClient then |
1050 | g_soundManager:stopSample(spec.samples.door) |
1051 | end |
1052 | end |
1053 | end |
1054 | |
1055 | -- on client side it can happen that the baler is closed 1 frame before the animation is synced completelly |
1056 | -- in this case we drop the bale here |
1057 | if spec.unloadingState == Baler.UNLOADING_OPEN or spec.unloadingState == Baler.UNLOADING_CLOSING then |
1058 | if not self.isServer then |
1059 | if #spec.bales > 0 then |
1060 | self:dropBale(1) |
1061 | end |
1062 | end |
1063 | end |
1064 | |
1065 | Baler.updateActionEvents(self) |
1066 | |
1067 | if self.isServer then |
1068 | --automatically drop bale and close door afterwards |
1069 | if (spec.automaticDrop ~= nil and spec.automaticDrop) or self:getIsAIActive() then |
1070 | if self:isUnloadingAllowed() then |
1071 | if spec.hasUnloadingAnimation or spec.allowsBaleUnloading then |
1072 | if spec.unloadingState == Baler.UNLOADING_CLOSED then |
1073 | if #spec.bales > 0 then |
1074 | self:setIsUnloadingBale(true) |
1075 | end |
1076 | end |
1077 | end |
1078 | end |
1079 | |
1080 | if spec.hasUnloadingAnimation then |
1081 | if spec.unloadingState == Baler.UNLOADING_OPEN then |
1082 | self:setIsUnloadingBale(false) |
1083 | end |
1084 | end |
1085 | end |
1086 | |
1087 | spec.pickUpLitersBuffer:add(spec.workAreaParameters.lastPickedUpLiters) |
1088 | |
1089 | if spec.platformAutomaticDrop then |
1090 | if spec.platformReadyToDrop then |
1091 | self:dropBaleFromPlatform(true) |
1092 | end |
1093 | end |
1094 | |
1095 | -- automatically drop bale on platform if new bale is ready |
1096 | if spec.hasPlatform then |
1097 | if #spec.bales > 0 then |
1098 | if spec.platformReadyToDrop then |
1099 | self:dropBaleFromPlatform(true) |
1100 | end |
1101 | end |
1102 | |
1103 | -- mount the bale directly to the bale dropper since we never stop moving, so DynamicMountAttacher spec would mount it |
1104 | if spec.hasDynamicMountPlatform then |
1105 | if spec.platformMountDelay > 0 then |
1106 | spec.platformMountDelay = spec.platformMountDelay - 1 |
1107 | if spec.platformMountDelay == 0 then |
1108 | self:forceDynamicMountPendingObjects(true) |
1109 | end |
1110 | else |
1111 | -- play drop animation if bale was lost |
1112 | if spec.platformReadyToDrop then |
1113 | if not self:getHasDynamicMountedObjects() then |
1114 | self:dropBaleFromPlatform(false) |
1115 | end |
1116 | end |
1117 | end |
1118 | end |
1119 | end |
1120 | |
1121 | -- unload from buffer to bale chamber once it is full |
1122 | if spec.nonStopBaling then |
1123 | local bufferLevel = self:getFillUnitFillLevel(spec.buffer.fillUnitIndex) |
1124 | if bufferLevel > 0 then |
1125 | if bufferLevel == self:getFillUnitCapacity(spec.buffer.fillUnitIndex) then |
1126 | local capacity = self:getFillUnitCapacity(spec.fillUnitIndex) |
1127 | if capacity == 0 or capacity == math.huge or self:getFillUnitFreeCapacity(spec.fillUnitIndex) > 0 then |
1128 | if not spec.buffer.unloadingStarted then |
1129 | if spec.unloadingState == Baler.UNLOADING_CLOSED then |
1130 | spec.buffer.unloadingStarted = true |
1131 | |
1132 | if spec.buffer.overloadAnimation ~= nil then |
1133 | self:playAnimation(spec.buffer.overloadAnimation, spec.buffer.overloadAnimationSpeed) |
1134 | end |
1135 | end |
1136 | end |
1137 | end |
1138 | end |
1139 | |
1140 | if spec.buffer.unloadingStarted then |
1141 | if self:getFillUnitFreeCapacity(spec.fillUnitIndex) > 0 then |
1142 | local capacity = self:getFillUnitCapacity(spec.buffer.fillUnitIndex) |
1143 | local delta = math.min(capacity / spec.buffer.overloadingDuration * dt, bufferLevel) |
1144 | local fillType = self:getFillUnitFillType(spec.buffer.fillUnitIndex) |
1145 | local realDelta = self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.buffer.fillUnitIndex, -delta, fillType, ToolType.UNDEFINED, nil) |
1146 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, -realDelta, fillType, ToolType.UNDEFINED, nil) |
1147 | |
1148 | -- if we unload a unfinished bale we first empty the buffer, drop bale on platform and then unload the new bale |
1149 | if spec.buffer.fillLevelToEmpty > 0 then |
1150 | spec.buffer.fillLevelToEmpty = math.max(spec.buffer.fillLevelToEmpty - delta, 0) |
1151 | |
1152 | if spec.buffer.fillLevelToEmpty == 0 then |
1153 | spec.platformDelayedDropping = true |
1154 | spec.buffer.unloadingStarted = false |
1155 | end |
1156 | end |
1157 | end |
1158 | |
1159 | -- baler is full |
1160 | if self:getFillUnitFillLevelPercentage(spec.fillUnitIndex) == 1 then |
1161 | spec.buffer.unloadingStarted = false |
1162 | end |
1163 | end |
1164 | else |
1165 | if not spec.buffer.fillMainUnitAfterOverload then |
1166 | spec.buffer.unloadingStarted = false |
1167 | end |
1168 | end |
1169 | |
1170 | if spec.buffer.overloadAnimation ~= nil then |
1171 | if not self:getIsAnimationPlaying(spec.buffer.overloadAnimation) and self:getAnimationTime(spec.buffer.overloadAnimation) > 0.5 then |
1172 | self:playAnimation(spec.buffer.overloadAnimation, -spec.buffer.overloadAnimationSpeed) |
1173 | end |
1174 | end |
1175 | end |
1176 | end |
1177 | |
1178 | if self.isServer then |
1179 | if spec.showBaleLimitWarning ~= showBaleLimitWarning then |
1180 | spec.showBaleLimitWarning = showBaleLimitWarning |
1181 | self:raiseDirtyFlags(spec.dirtyFlag) |
1182 | end |
1183 | end |
1184 | |
1185 | if spec.hasPlatform then |
1186 | -- unload bale after last bale was dropped from platform |
1187 | if spec.platformDelayedDropping then |
1188 | if not spec.platformDropInProgress then |
1189 | Baler.actionEventUnloading(self) |
1190 | spec.platformDelayedDropping = false |
1191 | end |
1192 | end |
1193 | |
1194 | if spec.platformDropInProgress and not self:getIsAnimationPlaying(spec.platformAnimation) then |
1195 | spec.platformDropInProgress = false |
1196 | end |
1197 | end |
1198 | end |
onWriteStream
DescriptionDefinitiononWriteStream()Code
769 | function Baler:onWriteStream(streamId, connection) |
770 | local spec = self.spec_baler |
771 | |
772 | if spec.hasUnloadingAnimation then |
773 | streamWriteUIntN(streamId, spec.unloadingState, 7) |
774 | local animTime = 0 |
775 | if spec.unloadingState == Baler.UNLOADING_CLOSED or spec.unloadingState == Baler.UNLOADING_CLOSING then |
776 | animTime = self:getRealAnimationTime(spec.baleCloseAnimationName) |
777 | elseif spec.unloadingState == Baler.UNLOADING_OPEN or spec.unloadingState == Baler.UNLOADING_OPENING then |
778 | animTime = self:getRealAnimationTime(spec.baleUnloadAnimationName) |
779 | end |
780 | streamWriteFloat32(streamId, animTime) |
781 | end |
782 | |
783 | streamWriteUInt8(streamId, #spec.bales) |
784 | for i=1, #spec.bales do |
785 | local bale = spec.bales[i] |
786 | streamWriteIntN(streamId, bale.fillType, FillTypeManager.SEND_NUM_BITS) |
787 | streamWriteFloat32(streamId, bale.fillLevel) |
788 | if spec.baleAnimCurve ~= nil then |
789 | streamWriteFloat32(streamId, bale.time) |
790 | end |
791 | end |
792 | |
793 | streamWriteBool(streamId, spec.lastAreaBiggerZero) |
794 | |
795 | if spec.hasPlatform then |
796 | streamWriteBool(streamId, spec.platformReadyToDrop) |
797 | end |
798 | |
799 | streamWriteUIntN(streamId, spec.currentBaleTypeIndex, BalerBaleTypeEvent.BALE_TYPE_SEND_NUM_BITS) |
800 | streamWriteUIntN(streamId, spec.preSelectedBaleTypeIndex, BalerBaleTypeEvent.BALE_TYPE_SEND_NUM_BITS) |
801 | |
802 | streamWriteFloat32(streamId, self:getFillUnitCapacity(spec.fillUnitIndex)) |
803 | streamWriteFloat32(streamId, self:getFillUnitFillLevel(spec.fillUnitIndex)) |
804 | end |
onWriteUpdateStream
DescriptionDefinitiononWriteUpdateStream()Code
822 | function Baler:onWriteUpdateStream(streamId, connection, dirtyMask) |
823 | local spec = self.spec_baler |
824 | |
825 | if not connection:getIsServer() then |
826 | if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlag) ~= 0) then |
827 | streamWriteBool(streamId, spec.lastAreaBiggerZero) |
828 | streamWriteUIntN(streamId, spec.fillEffectTypeSent, FillTypeManager.SEND_NUM_BITS) |
829 | streamWriteBool(streamId, spec.showBaleLimitWarning) |
830 | end |
831 | end |
832 | end |
prerequisitesPresent
DescriptionDefinitionprerequisitesPresent()Code
160 | function Baler.prerequisitesPresent(specializations) |
161 | return SpecializationUtil.hasSpecialization(FillUnit, specializations) |
162 | and SpecializationUtil.hasSpecialization(WorkArea, specializations) |
163 | and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations) |
164 | and SpecializationUtil.hasSpecialization(AnimatedVehicle, specializations) |
165 | end |
processBalerArea
DescriptionDefinitionprocessBalerArea()Code
2086 | function Baler:processBalerArea(workArea, dt) |
2087 | local spec = self.spec_baler |
2088 | |
2089 | local lsx, lsy, lsz, lex, ley, lez, lineRadius = DensityMapHeightUtil.getLineByArea(workArea.start, workArea.width, workArea.height) |
2090 | if self.isServer then |
2091 | spec.fillEffectType = FillType.UNKNOWN |
2092 | end |
2093 | for fillTypeIndex, _ in pairs(spec.pickupFillTypes) do |
2094 | local pickedUpLiters = -DensityMapHeightUtil.tipToGroundAroundLine(self, -math.huge, fillTypeIndex, lsx, lsy, lsz, lex, ley, lez, lineRadius, nil, nil, false, nil) |
2095 | if pickedUpLiters > 0 then |
2096 | if self.isServer then |
2097 | spec.fillEffectType = fillTypeIndex |
2098 | |
2099 | if spec.additives.available then |
2100 | local fillTypeSupported = false |
2101 | for i=1, #spec.additives.fillTypes do |
2102 | if fillTypeIndex == spec.additives.fillTypes[i] then |
2103 | fillTypeSupported = true |
2104 | break |
2105 | end |
2106 | end |
2107 | |
2108 | if fillTypeSupported then |
2109 | local additivesFillLevel = self:getFillUnitFillLevel(spec.additives.fillUnitIndex) |
2110 | if additivesFillLevel > 0 then |
2111 | local usage = spec.additives.usage * pickedUpLiters |
2112 | if usage > 0 then |
2113 | local availableUsage = math.min(additivesFillLevel / usage, 1) |
2114 | |
2115 | pickedUpLiters = pickedUpLiters * (1 + 0.05 * availableUsage) |
2116 | |
2117 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.additives.fillUnitIndex, -usage, self:getFillUnitFillType(spec.additives.fillUnitIndex), ToolType.UNDEFINED) |
2118 | end |
2119 | end |
2120 | end |
2121 | end |
2122 | end |
2123 | |
2124 | spec.pickupFillTypes[fillTypeIndex] = spec.pickupFillTypes[fillTypeIndex] + pickedUpLiters |
2125 | |
2126 | spec.workAreaParameters.lastPickedUpLiters = spec.workAreaParameters.lastPickedUpLiters + pickedUpLiters |
2127 | |
2128 | return pickedUpLiters, pickedUpLiters |
2129 | end |
2130 | end |
2131 | |
2132 | return 0, 0 |
2133 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
212 | function Baler.registerEventListeners(vehicleType) |
213 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", Baler) |
214 | SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", Baler) |
215 | SpecializationUtil.registerEventListener(vehicleType, "onLoadFinished", Baler) |
216 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", Baler) |
217 | SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Baler) |
218 | SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Baler) |
219 | SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", Baler) |
220 | SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", Baler) |
221 | SpecializationUtil.registerEventListener(vehicleType, "onUpdate", Baler) |
222 | SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", Baler) |
223 | SpecializationUtil.registerEventListener(vehicleType, "onDraw", Baler) |
224 | SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", Baler) |
225 | SpecializationUtil.registerEventListener(vehicleType, "onStartWorkAreaProcessing", Baler) |
226 | SpecializationUtil.registerEventListener(vehicleType, "onEndWorkAreaProcessing", Baler) |
227 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOn", Baler) |
228 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOff", Baler) |
229 | SpecializationUtil.registerEventListener(vehicleType, "onRootVehicleChanged", Baler) |
230 | SpecializationUtil.registerEventListener(vehicleType, "onChangedFillType", Baler) |
231 | SpecializationUtil.registerEventListener(vehicleType, "onFillUnitFillLevelChanged", Baler) |
232 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
169 | function Baler.registerFunctions(vehicleType) |
170 | SpecializationUtil.registerFunction(vehicleType, "processBalerArea", Baler.processBalerArea) |
171 | |
172 | SpecializationUtil.registerFunction(vehicleType, "setBaleTypeIndex", Baler.setBaleTypeIndex) |
173 | SpecializationUtil.registerFunction(vehicleType, "isUnloadingAllowed", Baler.isUnloadingAllowed) |
174 | SpecializationUtil.registerFunction(vehicleType, "getTimeFromLevel", Baler.getTimeFromLevel) |
175 | SpecializationUtil.registerFunction(vehicleType, "moveBales", Baler.moveBales) |
176 | SpecializationUtil.registerFunction(vehicleType, "moveBale", Baler.moveBale) |
177 | SpecializationUtil.registerFunction(vehicleType, "setIsUnloadingBale", Baler.setIsUnloadingBale) |
178 | SpecializationUtil.registerFunction(vehicleType, "getIsBaleUnloading", Baler.getIsBaleUnloading) |
179 | SpecializationUtil.registerFunction(vehicleType, "dropBale", Baler.dropBale) |
180 | SpecializationUtil.registerFunction(vehicleType, "finishBale", Baler.finishBale) |
181 | SpecializationUtil.registerFunction(vehicleType, "createBale", Baler.createBale) |
182 | SpecializationUtil.registerFunction(vehicleType, "setBaleTime", Baler.setBaleTime) |
183 | SpecializationUtil.registerFunction(vehicleType, "getCanUnloadUnfinishedBale", Baler.getCanUnloadUnfinishedBale) |
184 | SpecializationUtil.registerFunction(vehicleType, "setBalerAutomaticDrop", Baler.setBalerAutomaticDrop) |
185 | SpecializationUtil.registerFunction(vehicleType, "updateDummyBale", Baler.updateDummyBale) |
186 | SpecializationUtil.registerFunction(vehicleType, "deleteDummyBale", Baler.deleteDummyBale) |
187 | SpecializationUtil.registerFunction(vehicleType, "createDummyBale", Baler.createDummyBale) |
188 | SpecializationUtil.registerFunction(vehicleType, "handleUnloadingBaleEvent", Baler.handleUnloadingBaleEvent) |
189 | SpecializationUtil.registerFunction(vehicleType, "dropBaleFromPlatform", Baler.dropBaleFromPlatform) |
190 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
194 | function Baler.registerOverwrittenFunctions(vehicleType) |
195 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadSpeedRotatingPartFromXML", Baler.loadSpeedRotatingPartFromXML) |
196 | |
197 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "doCheckSpeedLimit", Baler.doCheckSpeedLimit) |
198 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsSpeedRotatingPartActive", Baler.getIsSpeedRotatingPartActive) |
199 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeTurnedOn", Baler.getCanBeTurnedOn) |
200 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsFoldAllowed", Baler.getIsFoldAllowed) |
201 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsWorkAreaActive", Baler.getIsWorkAreaActive) |
202 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getConsumingLoad", Baler.getConsumingLoad) |
203 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", Baler.getCanBeSelected) |
204 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsAttachedTo", Baler.getIsAttachedTo) |
205 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAllowDynamicMountFillLevelInfo", Baler.getAllowDynamicMountFillLevelInfo) |
206 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAlarmTriggerIsActive", Baler.getAlarmTriggerIsActive) |
207 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadAlarmTrigger", Baler.loadAlarmTrigger) |
208 | end |
saveToXMLFile
DescriptionDefinitionsaveToXMLFile()Code
678 | function Baler:saveToXMLFile(xmlFile, key, usedModNames) |
679 | local spec = self.spec_baler |
680 | -- never save bales on round balers since they can only have one bale and that is saved in the fillUnit |
681 | -- if the fill unit is not full we try to save the bale (maybe the user saves while unloading) |
682 | if not spec.hasUnloadingAnimation or self:getFillUnitFreeCapacity(spec.fillUnitIndex) > 0 then |
683 | xmlFile:setValue(key.."#numBales", #spec.bales) |
684 | |
685 | for k, bale in ipairs(spec.bales) do |
686 | local baleKey = string.format("%s.bale(%d)", key, k-1) |
687 | xmlFile:setValue(baleKey.."#filename", bale.filename) |
688 | |
689 | local fillTypeStr = "UNKNOWN" |
690 | if bale.fillType ~= FillType.UNKNOWN then |
691 | fillTypeStr = g_fillTypeManager:getFillTypeNameByIndex(bale.fillType) |
692 | end |
693 | xmlFile:setValue(baleKey.."#fillType", fillTypeStr) |
694 | xmlFile:setValue(baleKey.."#fillLevel", bale.fillLevel) |
695 | |
696 | if spec.baleAnimCurve ~= nil then |
697 | xmlFile:setValue(baleKey.."#baleTime", bale.time) |
698 | end |
699 | end |
700 | end |
701 | |
702 | if spec.hasPlatform then |
703 | xmlFile:setValue(key.."#platformReadyToDrop", spec.platformReadyToDrop) |
704 | end |
705 | |
706 | xmlFile:setValue(key.."#baleTypeIndex", spec.currentBaleTypeIndex) |
707 | xmlFile:setValue(key.."#preSelectedBaleTypeIndex", spec.preSelectedBaleTypeIndex) |
708 | |
709 | xmlFile:setValue(key.."#fillUnitCapacity", self:getFillUnitCapacity(spec.fillUnitIndex)) |
710 | |
711 | if spec.nonStopBaling then |
712 | xmlFile:setValue(key.."#bufferUnloadingStarted", spec.buffer.unloadingStarted) |
713 | end |
714 | end |
setBalerAutomaticDrop
DescriptionSets automatic drop stateDefinition
setBalerAutomaticDrop()Code
1930 | function Baler:setBalerAutomaticDrop(state, noEventSend) |
1931 | local spec = self.spec_baler |
1932 | if state == nil then |
1933 | if spec.hasPlatform then |
1934 | state = not spec.platformAutomaticDrop |
1935 | else |
1936 | state = not spec.automaticDrop |
1937 | end |
1938 | end |
1939 | |
1940 | if spec.hasPlatform then |
1941 | spec.platformAutomaticDrop = state |
1942 | else |
1943 | spec.automaticDrop = state |
1944 | end |
1945 | |
1946 | -- update so we have the unloading action events |
1947 | self:requestActionEventUpdate() |
1948 | |
1949 | BalerAutomaticDropEvent.sendEvent(self, state, noEventSend) |
1950 | end |
setBaleTime
DescriptionDefinitionsetBaleTime()Code
1571 | function Baler:setBaleTime(i, baleTime, noEventSend) |
1572 | local spec = self.spec_baler |
1573 | |
1574 | if spec.baleAnimCurve ~= nil then |
1575 | local bale = spec.bales[i] |
1576 | if bale ~= nil then |
1577 | bale.time = baleTime |
1578 | if self.isServer then |
1579 | local v = spec.baleAnimCurve:get(bale.time) |
1580 | setTranslation(bale.baleJointNode, v[1], v[2], v[3]) |
1581 | setRotation(bale.baleJointNode, v[4], v[5], v[6]) |
1582 | if bale.baleJointIndex ~= 0 then |
1583 | setJointFrame(bale.baleJointIndex, 0, bale.baleJointNode) |
1584 | end |
1585 | end |
1586 | if bale.time >= 1 then |
1587 | self:dropBale(i) |
1588 | end |
1589 | if #spec.bales == 0 then |
1590 | spec.isBaleUnloading = false |
1591 | |
1592 | if self.isClient then |
1593 | g_soundManager:stopSample(spec.samples.unload) |
1594 | end |
1595 | end |
1596 | if self.isServer then |
1597 | if noEventSend == nil or not noEventSend then |
1598 | g_server:broadcastEvent(BalerSetBaleTimeEvent.new(self, i, bale.time), nil, nil, self) |
1599 | end |
1600 | end |
1601 | end |
1602 | end |
1603 | end |
setBaleTypeIndex
DescriptionDefinitionsetBaleTypeIndex()Code
1403 | function Baler:setBaleTypeIndex(baleTypeIndex, force, noEventSend) |
1404 | local spec = self.spec_baler |
1405 | |
1406 | spec.preSelectedBaleTypeIndex = baleTypeIndex |
1407 | if self:getFillUnitFillLevel(spec.fillUnitIndex) == 0 or force then |
1408 | spec.currentBaleTypeIndex = baleTypeIndex |
1409 | end |
1410 | |
1411 | Baler.updateActionEvents(self) |
1412 | |
1413 | BalerBaleTypeEvent.sendEvent(self, baleTypeIndex, force, noEventSend) |
1414 | end |
setIsUnloadingBale
DescriptionDefinitionsetIsUnloadingBale()Code
1481 | function Baler:setIsUnloadingBale(isUnloadingBale, noEventSend) |
1482 | local spec = self.spec_baler |
1483 | |
1484 | if spec.hasUnloadingAnimation then |
1485 | if isUnloadingBale then |
1486 | if spec.unloadingState ~= Baler.UNLOADING_OPENING then |
1487 | |
1488 | if #spec.bales == 0 and spec.canUnloadUnfinishedBale and self:getFillUnitFillLevel(spec.fillUnitIndex) > spec.unfinishedBaleThreshold then |
1489 | local fillTypeIndex = self:getFillUnitFillType(spec.fillUnitIndex) |
1490 | local currentFillLevel = self:getFillUnitFillLevel(spec.fillUnitIndex) |
1491 | local delta = self:getFillUnitFreeCapacity(spec.fillUnitIndex) |
1492 | spec.lastBaleFillLevel = currentFillLevel |
1493 | self:setFillUnitFillLevelToDisplay(spec.fillUnitIndex, currentFillLevel) |
1494 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, delta, fillTypeIndex, ToolType.UNDEFINED) |
1495 | spec.buffer.unloadingStarted = false |
1496 | end |
1497 | |
1498 | BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend) |
1499 | spec.unloadingState = Baler.UNLOADING_OPENING |
1500 | if self.isClient then |
1501 | g_soundManager:playSample(spec.samples.eject) |
1502 | g_soundManager:playSample(spec.samples.door) |
1503 | end |
1504 | |
1505 | local baleTypeDef = spec.baleTypes[spec.currentBaleTypeIndex] |
1506 | self:playAnimation(baleTypeDef.animations.unloading, baleTypeDef.animations.unloadingSpeed, nil, true) |
1507 | end |
1508 | else |
1509 | if spec.unloadingState ~= Baler.UNLOADING_CLOSING and spec.unloadingState ~= Baler.UNLOADING_CLOSED then |
1510 | BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend) |
1511 | spec.unloadingState = Baler.UNLOADING_CLOSING |
1512 | if self.isClient then |
1513 | g_soundManager:playSample(spec.samples.door) |
1514 | end |
1515 | self:playAnimation(spec.baleCloseAnimationName, spec.baleCloseAnimationSpeed, nil, true) |
1516 | end |
1517 | end |
1518 | elseif spec.allowsBaleUnloading then |
1519 | if isUnloadingBale then |
1520 | BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend) |
1521 | spec.isBaleUnloading = true |
1522 | |
1523 | if self.isClient then |
1524 | g_soundManager:playSample(spec.samples.unload) |
1525 | end |
1526 | end |
1527 | end |
1528 | end |
updateActionEvents
DescriptionDefinitionupdateActionEvents()Code
2285 | function Baler.updateActionEvents(self) |
2286 | local spec = self.spec_baler |
2287 | local actionEvent = spec.actionEvents[InputAction.IMPLEMENT_EXTRA3] |
2288 | if actionEvent ~= nil then |
2289 | local showAction = false |
2290 | |
2291 | if self:isUnloadingAllowed() then |
2292 | if spec.hasUnloadingAnimation or spec.allowsBaleUnloading then |
2293 | |
2294 | if spec.unloadingState == Baler.UNLOADING_CLOSED then |
2295 | if self:getCanUnloadUnfinishedBale() then |
2296 | g_inputBinding:setActionEventText(actionEvent.actionEventId, spec.texts.unloadUnfinishedBale) |
2297 | showAction = true |
2298 | end |
2299 | if #spec.bales > 0 then |
2300 | g_inputBinding:setActionEventText(actionEvent.actionEventId, spec.texts.unloadBaler) |
2301 | showAction = true |
2302 | end |
2303 | elseif spec.unloadingState == Baler.UNLOADING_OPEN then |
2304 | if spec.hasUnloadingAnimation then |
2305 | g_inputBinding:setActionEventText(actionEvent.actionEventId, spec.texts.closeBack) |
2306 | showAction = true |
2307 | end |
2308 | end |
2309 | end |
2310 | end |
2311 | |
2312 | if spec.platformReadyToDrop then |
2313 | g_inputBinding:setActionEventText(actionEvent.actionEventId, spec.texts.unloadBaler) |
2314 | showAction = true |
2315 | end |
2316 | |
2317 | g_inputBinding:setActionEventActive(actionEvent.actionEventId, showAction) |
2318 | end |
2319 | |
2320 | if spec.toggleableAutomaticDrop then |
2321 | actionEvent = spec.actionEvents[InputAction.IMPLEMENT_EXTRA4] |
2322 | if actionEvent ~= nil then |
2323 | local automaticDropState = spec.automaticDrop |
2324 | if spec.hasPlatform then |
2325 | automaticDropState = spec.platformAutomaticDrop |
2326 | end |
2327 | g_inputBinding:setActionEventText(actionEvent.actionEventId, automaticDropState and spec.toggleAutomaticDropTextNeg or spec.toggleAutomaticDropTextPos) |
2328 | end |
2329 | end |
2330 | |
2331 | if #spec.baleTypes > 1 then |
2332 | actionEvent = spec.actionEvents[InputAction.TOGGLE_BALE_TYPES] |
2333 | if actionEvent ~= nil then |
2334 | local baleTypeDef = spec.baleTypes[spec.preSelectedBaleTypeIndex] |
2335 | local baleSize |
2336 | if spec.hasUnloadingAnimation then |
2337 | baleSize = baleTypeDef.diameter |
2338 | else |
2339 | baleSize = baleTypeDef.length |
2340 | end |
2341 | |
2342 | g_inputBinding:setActionEventText(actionEvent.actionEventId, spec.changeBaleTypeText:format(baleSize * 100)) |
2343 | end |
2344 | end |
2345 | end |
updateDummyBale
DescriptionDefinitionupdateDummyBale()Code
1843 | function Baler:updateDummyBale(dummyBaleData, fillTypeIndex, fillLevel, capacity) |
1844 | local spec = self.spec_baler |
1845 | local baleTypeDef = dummyBaleData.baleTypeDef or spec.baleTypes[spec.currentBaleTypeIndex] |
1846 | local generatedBale = false |
1847 | local baleNode = dummyBaleData.linkNode or baleTypeDef.baleNode |
1848 | if baleNode ~= nil and fillLevel > 0 and fillLevel < capacity and (dummyBaleData.currentBale == nil or dummyBaleData.currentBaleFillType ~= fillTypeIndex) then |
1849 | if dummyBaleData.currentBale ~= nil then |
1850 | self:deleteDummyBale(dummyBaleData) |
1851 | end |
1852 | |
1853 | self:createDummyBale(dummyBaleData, fillTypeIndex) |
1854 | generatedBale = true |
1855 | end |
1856 | |
1857 | if dummyBaleData.currentBale ~= nil then |
1858 | local scaleNode = dummyBaleData.linkNode or baleTypeDef.scaleNode |
1859 | if scaleNode ~= nil and capacity > 0 then |
1860 | local percentage = fillLevel / capacity |
1861 | local x = 1 |
1862 | local y = baleTypeDef.isRoundBale and percentage or 1 |
1863 | local z = percentage |
1864 | |
1865 | local scaleComponents = dummyBaleData.scaleComponents or baleTypeDef.scaleComponents |
1866 | if scaleComponents ~= nil then |
1867 | x, y, z = 1, 1, 1 |
1868 | for axis, value in ipairs(scaleComponents) do |
1869 | if value > 0 then |
1870 | if axis == 1 then |
1871 | x = percentage * value |
1872 | elseif axis == 2 then |
1873 | y = percentage * value |
1874 | else |
1875 | z = percentage * value |
1876 | end |
1877 | end |
1878 | end |
1879 | end |
1880 | |
1881 | setScale(scaleNode, x, y, z) |
1882 | end |
1883 | end |
1884 | |
1885 | return generatedBale |
1886 | end |