Script v1.7.1.0
- AI
- Animals
- Contracts
- Debug
- Economy
- Effects
- Events
- Farms
- GUI
- Handtools
- I3d
- Materials
- Misc
- Objects
- Placeables
- Player
- Shop
- Sounds
- Specializations
- AIConveyorBelt
- AIImplement
- AIVehicle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BaseMaterial
- BunkerSiloCompacter
- BunkerSiloInteractor
- BuyableBale
- CCTDrivable
- Combine
- ConnectionHoses
- ConveyorBelt
- Cover
- CrabSteering
- Crawlers
- Cultivator
- Cutter
- Cylindered
- CylinderedFoldable
- Dashboard
- Dischargeable
- Drivable
- DynamicallyLoadedParts
- DynamicMountAttacher
- Enterable
- FertilizingCultivator
- FertilizingSowingMachine
- FillTriggerVehicle
- FillUnit
- FillVolume
- Foldable
- FoliageBending
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- GroundAdjustedNodes
- GroundReference
- Honk
- HookLiftContainer
- HookLiftTrailer
- IKChains
- JigglingParts
- Leveler
- Lights
- LivestockTrailer
- Locomotive
- LogGrab
- ManureBarrel
- MixerWagon
- Motorized
- Mountable
- Mower
- Pickup
- Pipe
- Plow
- PowerConsumer
- PowerTakeOffs
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- Rideable
- RidgeMarker
- Roller
- Ropes
- SemiTrailerFront
- Shovel
- SlopeCompensation
- SmartAttach
- SowingMachine
- SpeedRotatingParts
- SplineVehicle
- Sprayer
- StrawBlower
- StumpCutter
- Suspensions
- Tedder
- TensionBeltObject
- TensionBelts
- TipOccluder
- Trailer
- TreePlanter
- TreeSaw
- TurnOnVehicle
- Washable
- WaterTrailer
- Wearable
- Weeder
- Wheels
- Windrower
- Wipers
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkMode
- WorkParticles
- Triggers
- Utils
- Vehicles
- Weather
Engine v1.7.1.0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- XML
- general
Foundation Reference
BaleWrapper
DescriptionSpecialization for all BaleWrappers (round, square) providing picking up, wrapping and dropping functionalityFunctions
- actionEventEmpty
- allowsGrabbingBale
- doStateChange
- getBaleInRange
- getCanBeSelected
- getIsBaleFillTypeSkiped
- getIsFoldAllowed
- getWrapperBaleType
- initSpecialization
- loadWrapperFromXML
- onDeactivate
- onDelete
- onDraw
- onLoad
- onLoadFinished
- onPostLoad
- onReadStream
- onRegisterActionEvents
- onUpdate
- onUpdateTick
- onWriteStream
- pickupWrapperBale
- playMoveToWrapper
- prerequisitesPresent
- registerEventListeners
- registerFunctions
- registerOverwrittenFunctions
- saveToXMLFile
- updateWrapNodes
- updateWrappingState
actionEventEmpty
DescriptionDefinitionactionEventEmpty()Code
1131 | function BaleWrapper.actionEventEmpty(self, actionName, inputValue, callbackState, isAnalog) |
1132 | local spec = self.spec_baleWrapper |
1133 | if spec.baleWrapperState == BaleWrapper.STATE_WRAPPER_FINSIHED then |
1134 | g_client:getServerConnection():sendEvent(BaleWrapperStateEvent:new(self, BaleWrapper.CHANGE_BUTTON_EMPTY)) |
1135 | end |
1136 | end |
allowsGrabbingBale
DescriptionReturns if allows bale grabbingDefinition
allowsGrabbingBale()Return Values
boolean | allows | allows bale grabbing |
678 | function BaleWrapper:allowsGrabbingBale() |
679 | local spec = self.spec_baleWrapper |
680 | local specFoldable = self.spec_foldable |
681 | if specFoldable ~= nil then |
682 | if specFoldable.foldAnimTime ~= nil and (specFoldable.foldAnimTime > spec.currentWrapperFoldMaxLimit or specFoldable.foldAnimTime < spec.currentWrapperFoldMinLimit) then |
683 | return false |
684 | end |
685 | end |
686 | |
687 | if spec.baleToLoad ~= nil then |
688 | return false |
689 | end |
690 | |
691 | return spec.baleWrapperState == BaleWrapper.STATE_NONE |
692 | end |
doStateChange
DescriptionChanged wrapper stateDefinition
doStateChange(integer id, integer nearestBaleServerId)Arguments
integer | id | id of new state |
integer | nearestBaleServerId | server id of nearest bale |
822 | function BaleWrapper:doStateChange(id, nearestBaleServerId) |
823 | local spec = self.spec_baleWrapper |
824 | |
825 | if id == BaleWrapper.CHANGE_WRAPPING_START or (spec.baleWrapperState ~= BaleWrapper.STATE_WRAPPER_FINSIHED and id == BaleWrapper.CHANGE_WRAPPER_START_DROP_BALE) then |
826 | if self:getIsBaleFillTypeSkiped(NetworkUtil.getObject(spec.currentWrapper.currentBale)) then |
827 | if self.isServer then |
828 | spec.setWrappingStateFinished = true |
829 | end |
830 | |
831 | return |
832 | end |
833 | end |
834 | |
835 | if id == BaleWrapper.CHANGE_GRAB_BALE then |
836 | local bale = NetworkUtil.getObject(nearestBaleServerId) |
837 | spec.baleGrabber.currentBale = nearestBaleServerId |
838 | if bale ~= nil then |
839 | local x,y,z = localToLocal(bale.nodeId, getParent(spec.baleGrabber.grabNode), 0,0,0) |
840 | setTranslation(spec.baleGrabber.grabNode, x,y,z) |
841 | bale:mount(self, spec.baleGrabber.grabNode, 0,0,0, 0,0,0) |
842 | spec.baleToMount = nil |
843 | spec:playMoveToWrapper(bale) |
844 | else |
845 | spec.baleToMount = {serverId=nearestBaleServerId, linkNode=spec.baleGrabber.grabNode, trans={0,0,0}, rot={0,0,0} } |
846 | end |
847 | spec.baleWrapperState = BaleWrapper.STATE_MOVING_BALE_TO_WRAPPER |
848 | |
849 | elseif id == BaleWrapper.CHANGE_DROP_BALE_AT_GRABBER then |
850 | -- drop bale at wrapper |
851 | local attachNode = spec.currentWrapper.baleNode |
852 | local bale = NetworkUtil.getObject(spec.baleGrabber.currentBale) |
853 | if bale ~= nil then |
854 | bale:mount(self, attachNode, 0,0,0, 0,0,0) |
855 | spec.baleToMount = nil |
856 | else |
857 | spec.baleToMount = {serverId=spec.baleGrabber.currentBale, linkNode=attachNode, trans={0,0,0}, rot={0,0,0} } |
858 | end |
859 | self:updateWrapNodes(true, false, 0) |
860 | |
861 | spec.currentWrapper.currentBale = spec.baleGrabber.currentBale |
862 | spec.baleGrabber.currentBale = nil |
863 | |
864 | if spec.currentWrapper.animations["moveToWrapper"].animName ~= nil then |
865 | if spec.currentWrapper.animations["moveToWrapper"].reverseAfterMove then |
866 | self:playAnimation(spec.currentWrapper.animations["moveToWrapper"].animName, -spec.currentWrapper.animations["moveToWrapper"].animSpeed, nil, true) |
867 | end |
868 | end |
869 | |
870 | spec.baleWrapperState = BaleWrapper.STATE_MOVING_GRABBER_TO_WORK |
871 | |
872 | elseif id == BaleWrapper.CHANGE_WRAPPING_START then |
873 | |
874 | spec.baleWrapperState = BaleWrapper.STATE_WRAPPER_WRAPPING_BALE |
875 | if self.isClient then |
876 | g_soundManager:playSample(spec.currentWrapper.samples.start) |
877 | g_soundManager:playSample(spec.currentWrapper.samples.wrap, 0, spec.currentWrapper.samples.start) |
878 | end |
879 | |
880 | if spec.currentWrapper.animations["wrapBale"].animName ~= nil then |
881 | self:playAnimation(spec.currentWrapper.animations["wrapBale"].animName, spec.currentWrapper.animations["wrapBale"].animSpeed, nil, true) |
882 | end |
883 | |
884 | if self.isServer then |
885 | for _, collision in pairs(spec.currentWrapper.collisions) do |
886 | setCollisionMask(collision.node, collision.activeCollisionMask); |
887 | end; |
888 | end; |
889 | elseif id == BaleWrapper.CHANGE_WRAPPING_BALE_FINSIHED then |
890 | |
891 | if self.isClient then |
892 | g_soundManager:stopSample(spec.currentWrapper.samples.wrap) |
893 | g_soundManager:stopSample(spec.currentWrapper.samples.stop) |
894 | if spec.currentWrapper.wrappingSoundEndTime == 1 then |
895 | g_soundManager:playSample(spec.currentWrapper.samples.stop) |
896 | end |
897 | |
898 | -- if the start sound is still playing (e.g. on loading if the wrapping state is directly set to 1) we stop it |
899 | if g_soundManager:getIsSamplePlaying(spec.currentWrapper.samples.start) then |
900 | g_soundManager:stopSample(spec.currentWrapper.samples.start) |
901 | end |
902 | end |
903 | |
904 | self:updateWrappingState(1, true) |
905 | spec.baleWrapperState = BaleWrapper.STATE_WRAPPER_FINSIHED |
906 | |
907 | if self:getIsBaleFillTypeSkiped(NetworkUtil.getObject(spec.currentWrapper.currentBale)) then |
908 | self:updateWrappingState(0, true) |
909 | end |
910 | elseif id == BaleWrapper.CHANGE_WRAPPER_START_DROP_BALE then |
911 | |
912 | self:updateWrapNodes(false, false, 0) |
913 | if spec.currentWrapper.animations["dropFromWrapper"].animName ~= nil then |
914 | self:playAnimation(spec.currentWrapper.animations["dropFromWrapper"].animName, spec.currentWrapper.animations["dropFromWrapper"].animSpeed, nil, true) |
915 | end |
916 | spec.baleWrapperState = BaleWrapper.STATE_WRAPPER_DROPPING_BALE |
917 | |
918 | if self.isServer then |
919 | for _, collision in pairs(spec.currentWrapper.collisions) do |
920 | setCollisionMask(collision.node, collision.inActiveCollisionMask); |
921 | end; |
922 | end; |
923 | elseif id == BaleWrapper.CHANGE_WRAPPER_BALE_DROPPED then |
924 | |
925 | local bale = NetworkUtil.getObject(spec.currentWrapper.currentBale) |
926 | if bale ~= nil then |
927 | bale:unmount() |
928 | end |
929 | spec.lastDroppedBale = bale |
930 | spec.currentWrapper.currentBale = nil |
931 | spec.currentWrapper.currentTime = 0 |
932 | if spec.currentWrapper.animations["resetAfterDrop"].animName ~= nil then |
933 | self:playAnimation(spec.currentWrapper.animations["resetAfterDrop"].animName, spec.currentWrapper.animations["resetAfterDrop"].animSpeed, nil, true) |
934 | end |
935 | spec.baleWrapperState = BaleWrapper.STATE_WRAPPER_RESETTING_PLATFORM |
936 | |
937 | elseif id == BaleWrapper.CHANGE_WRAPPER_PLATFORM_RESET then |
938 | |
939 | self:updateWrappingState(0) |
940 | self:updateWrapNodes(false, true, 0) |
941 | spec.baleWrapperState = BaleWrapper.STATE_NONE |
942 | |
943 | elseif id == BaleWrapper.CHANGE_BUTTON_EMPTY then |
944 | |
945 | -- Server only code |
946 | assert(self.isServer) |
947 | if spec.baleWrapperState == BaleWrapper.STATE_WRAPPER_FINSIHED then |
948 | g_server:broadcastEvent(BaleWrapperStateEvent:new(self, BaleWrapper.CHANGE_WRAPPER_START_DROP_BALE), true, nil, self) |
949 | end |
950 | |
951 | end |
952 | end |
getBaleInRange
DescriptionReturns if nearest bale in rangeDefinition
getBaleInRange(integer refNode, float distance)Arguments
integer | refNode | id of reference node |
float | distance | max distance |
table | nearestBale | nearest bale |
integer | nearestBaleType | id of bale type |
1049 | function BaleWrapper.getBaleInRange(self, refNode, distance) |
1050 | local nearestDistance = distance |
1051 | local nearestBale = nil |
1052 | local nearestBaleType |
1053 | |
1054 | for _, item in pairs(g_currentMission.itemsToSave) do |
1055 | local bale = item.item |
1056 | if bale:isa(Bale) then |
1057 | local maxDist |
1058 | if bale.baleDiameter ~= nil then |
1059 | maxDist = math.min(bale.baleDiameter, bale.baleWidth) |
1060 | else |
1061 | maxDist = math.min(bale.baleLength, bale.baleHeight, bale.baleWidth) |
1062 | end |
1063 | local _,_,z = localToLocal(bale.nodeId, refNode, 0,0,0) |
1064 | if math.abs(z) < maxDist and calcDistanceFrom(refNode, bale.nodeId) < nearestDistance then |
1065 | local foundBaleType |
1066 | if not bale.supportsWrapping or bale.wrappingState < 0.99 then |
1067 | foundBaleType = self:getWrapperBaleType(bale) |
1068 | end |
1069 | if foundBaleType ~= nil or nearestBaleType == nil then |
1070 | if foundBaleType ~= nil then |
1071 | nearestDistance = distance |
1072 | end |
1073 | nearestBale = bale |
1074 | nearestBaleType = foundBaleType |
1075 | end |
1076 | end |
1077 | end |
1078 | end |
1079 | return nearestBale, nearestBaleType |
1080 | end |
getCanBeSelected
DescriptionDefinitiongetCanBeSelected()Code
1097 | function BaleWrapper:getCanBeSelected(superFunc) |
1098 | return true |
1099 | end |
getIsBaleFillTypeSkiped
DescriptionDefinitiongetIsBaleFillTypeSkiped()Code
1014 | function BaleWrapper:getIsBaleFillTypeSkiped(bale) |
1015 | if bale == nil then |
1016 | return false |
1017 | end |
1018 | |
1019 | local spec = self.spec_baleWrapper |
1020 | local wrapper = spec.roundBaleWrapper |
1021 | if not bale.baleDiameter == nil then |
1022 | wrapper = spec.squareBaleWrapper |
1023 | end |
1024 | |
1025 | local isBaleSupported = false |
1026 | for fillTypeIndex, baleTypes in pairs(wrapper.allowedBaleTypes) do |
1027 | for _, baleType in pairs(baleTypes) do |
1028 | if bale.i3dFilename == baleType.wrapperBaleFilename -- if bale is already picked up and has new fillType |
1029 | or bale.fillType == fillTypeIndex then -- if bale is going to be picked up and has old fillType |
1030 | isBaleSupported = true |
1031 | break |
1032 | end |
1033 | end |
1034 | end |
1035 | |
1036 | if not isBaleSupported and wrapper.skipUnsupportedBales then |
1037 | return true |
1038 | end |
1039 | |
1040 | return false |
1041 | end |
getIsFoldAllowed
DescriptionReturns if fold is allowedDefinition
getIsFoldAllowed(boolean onAiTurnOn)Arguments
boolean | onAiTurnOn | called on ai turn on |
boolean | allowsFold | allows folding |
1086 | function BaleWrapper:getIsFoldAllowed(superFunc, direction, onAiTurnOn) |
1087 | local spec = self.spec_baleWrapper |
1088 | if spec.baleWrapperState ~= BaleWrapper.STATE_NONE then |
1089 | return false |
1090 | end |
1091 | |
1092 | return superFunc(self, direction, onAiTurnOn) |
1093 | end |
getWrapperBaleType
DescriptionReturns type of wrapped baleDefinition
getWrapperBaleType(table bale)Arguments
table | bale | unwrapped bale |
table | baleType | wrapped bale |
958 | function BaleWrapper:getWrapperBaleType(bale) |
959 | local spec = self.spec_baleWrapper |
960 | |
961 | local baleTypes |
962 | if bale.baleDiameter ~= nil then |
963 | baleTypes = spec.roundBaleWrapper.allowedBaleTypes[bale:getFillType()] |
964 | else |
965 | baleTypes = spec.squareBaleWrapper.allowedBaleTypes[bale:getFillType()] |
966 | end |
967 | if baleTypes ~= nil then |
968 | for _, baleType in pairs(baleTypes) do |
969 | if bale.baleDiameter ~= nil and bale.baleWidth ~= nil then |
970 | if bale.baleDiameter >= baleType.minBaleDiameter and bale.baleDiameter <= baleType.maxBaleDiameter and |
971 | bale.baleWidth >= baleType.minBaleWidth and bale.baleWidth <= baleType.maxBaleWidth |
972 | then |
973 | return baleType |
974 | end |
975 | elseif bale.baleHeight ~= nil and bale.baleWidth ~= nil and bale.baleLength ~= nil then |
976 | if bale.baleHeight >= baleType.minBaleHeight and bale.baleHeight <= baleType.maxBaleHeight and |
977 | bale.baleWidth >= baleType.minBaleWidth and bale.baleWidth <= baleType.maxBaleWidth and |
978 | bale.baleLength >= baleType.minBaleLength and bale.baleLength <= baleType.maxBaleLength |
979 | then |
980 | return baleType |
981 | end |
982 | end |
983 | end |
984 | end |
985 | return nil |
986 | end |
initSpecialization
DescriptionDefinitioninitSpecialization()Code
85 | function BaleWrapper.initSpecialization() |
86 | g_configurationManager:addConfigurationType("wrappingColor", g_i18n:getText("configuration_wrappingColor"), nil, nil, ConfigurationUtil.getConfigColorSingleItemLoad, ConfigurationUtil.getConfigColorPostLoad, ConfigurationUtil.SELECTOR_COLOR) |
87 | end |
loadWrapperFromXML
DescriptionDefinitionloadWrapperFromXML()Code
160 | function BaleWrapper:loadWrapperFromXML(wrapper, xmlFile, baseKey) |
161 | wrapper.animations = {} |
162 | for _, animType in pairs({"moveToWrapper", "wrapBale", "dropFromWrapper", "resetAfterDrop"}) do |
163 | local key = string.format("%s.animations.%s", baseKey, animType) |
164 | local anim = {} |
165 | anim.animName = getXMLString(xmlFile, key .. "#animName") |
166 | anim.animSpeed = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#animSpeed"), 1) |
167 | anim.reverseAfterMove = Utils.getNoNil(getXMLBool(xmlFile, key .. "#reverseAfterMove"), true) |
168 | |
169 | if Utils.getNoNil(getXMLBool(xmlFile, key .. "#resetOnStart"), false) then |
170 | self:playAnimation(anim.animName, -1, 0.1, true) |
171 | AnimatedVehicle.updateAnimationByName(self, anim.animName, 9999999) |
172 | end |
173 | |
174 | wrapper.animations[animType] = anim |
175 | end |
176 | |
177 | wrapper.allowedBaleTypes = {} |
178 | local i = 0 |
179 | while true do |
180 | local key = string.format("%s.baleTypes.baleType(%d)", baseKey, i) |
181 | if not hasXMLProperty(xmlFile, key) then |
182 | break |
183 | end |
184 | |
185 | local wrapperBaleFilename = Utils.getFilename(getXMLString(xmlFile, key.."#wrapperBaleFilename"), self.baseDirectory) |
186 | if wrapperBaleFilename == nil or not fileExists(wrapperBaleFilename) then |
187 | g_logManager:xmlWarning(self.configFileName, "Unknown wrapper bale file '%s' for '%s'", tostring(wrapperBaleFilename), key) |
188 | break |
189 | end |
190 | |
191 | local fillTypeStr = getXMLString(xmlFile, key.."#fillType") |
192 | if fillTypeStr == nil or g_fillTypeManager:getFillTypeByName(fillTypeStr) == nil then |
193 | g_logManager:xmlWarning(self.configFileName, "Warning: invalid fillType '%s' for '%s' given!", tostring(fillTypeStr), key) |
194 | break |
195 | end |
196 | |
197 | local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(fillTypeStr) |
198 | wrapper.allowedBaleTypes[fillTypeIndex] = {} |
199 | local minBaleDiameter = getXMLFloat(xmlFile, key.."#minBaleDiameter") |
200 | local maxBaleDiameter = getXMLFloat(xmlFile, key.."#maxBaleDiameter") |
201 | local minBaleWidth = getXMLFloat(xmlFile, key.."#minBaleWidth") |
202 | local maxBaleWidth = getXMLFloat(xmlFile, key.."#maxBaleWidth") |
203 | if minBaleDiameter ~= nil and maxBaleDiameter ~= nil and minBaleWidth ~= nil and maxBaleWidth ~= nil then |
204 | table.insert(wrapper.allowedBaleTypes[fillTypeIndex], {fillType=fillTypeIndex, wrapperBaleFilename=wrapperBaleFilename, minBaleDiameter=minBaleDiameter, maxBaleDiameter=maxBaleDiameter, minBaleWidth=minBaleWidth, maxBaleWidth=maxBaleWidth}) |
205 | else |
206 | local minBaleHeight = getXMLFloat(xmlFile, key.."#minBaleHeight") |
207 | local maxBaleHeight = getXMLFloat(xmlFile, key.."#maxBaleHeight") |
208 | local minBaleLength = getXMLFloat(xmlFile, key.."#minBaleLength") |
209 | local maxBaleLength = getXMLFloat(xmlFile, key.."#maxBaleLength") |
210 | if minBaleWidth ~= nil and maxBaleWidth ~= nil and minBaleHeight ~= nil and maxBaleHeight ~= nil and minBaleLength ~= nil and maxBaleLength ~= nil then |
211 | table.insert(wrapper.allowedBaleTypes[fillTypeIndex], {fillType=fillTypeIndex, wrapperBaleFilename=wrapperBaleFilename, minBaleWidth=minBaleWidth, maxBaleWidth=maxBaleWidth, minBaleHeight=minBaleHeight, maxBaleHeight=maxBaleHeight, minBaleLength=minBaleLength, maxBaleLength=maxBaleLength}) |
212 | end |
213 | end |
214 | |
215 | i = i + 1 |
216 | end |
217 | |
218 | wrapper.baleNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, baseKey .. "#baleNode"), self.i3dMappings) |
219 | wrapper.wrapperNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, baseKey .. "#wrapperNode"), self.i3dMappings) |
220 | wrapper.wrapperRotAxis = Utils.getNoNil(getXMLInt(xmlFile, baseKey.."#wrapperRotAxis"), 2) |
221 | |
222 | local wrappingAnimCurve = AnimCurve:new(linearInterpolatorN) |
223 | i = 0 |
224 | while true do |
225 | local keyI = string.format("%s.wrapperAnimation.key(%d)", baseKey, i) |
226 | local t = getXMLFloat(xmlFile, keyI.."#time") |
227 | local baleX, baleY, baleZ = StringUtil.getVectorFromString(getXMLString(xmlFile, keyI.."#baleRot")) |
228 | if baleX == nil or baleY == nil or baleZ == nil then |
229 | break |
230 | end |
231 | baleX = math.rad(Utils.getNoNil(baleX, 0)) |
232 | baleY = math.rad(Utils.getNoNil(baleY, 0)) |
233 | baleZ = math.rad(Utils.getNoNil(baleZ, 0)) |
234 | local wrapperX, wrapperY, wrapperZ = StringUtil.getVectorFromString(getXMLString(xmlFile, keyI.."#wrapperRot")) |
235 | wrapperX = math.rad(Utils.getNoNil(wrapperX, 0)) |
236 | wrapperY = math.rad(Utils.getNoNil(wrapperY, 0)) |
237 | wrapperZ = math.rad(Utils.getNoNil(wrapperZ, 0)) |
238 | wrappingAnimCurve:addKeyframe({baleX, baleY, baleZ, wrapperX, wrapperY, wrapperZ, time = t}) |
239 | i = i +1 |
240 | end |
241 | |
242 | wrapper.animCurve = wrappingAnimCurve |
243 | wrapper.animTime = Utils.getNoNil(getXMLFloat(xmlFile, baseKey .. "#wrappingTime"), 5) * 1000 |
244 | wrapper.currentTime = 0 |
245 | wrapper.currentBale = nil |
246 | |
247 | wrapper.wrapAnimNodes = {} |
248 | i = 0 |
249 | while true do |
250 | local wrapAnimNodeKey = string.format("%s.wrapAnimNodes.wrapAnimNode(%d)", baseKey, i) |
251 | if not hasXMLProperty(xmlFile, wrapAnimNodeKey) then |
252 | break |
253 | end |
254 | local nodeId = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, wrapAnimNodeKey.."#index"), self.i3dMappings) |
255 | if nodeId ~= nil then |
256 | local animCurve = AnimCurve:new(linearInterpolatorN) |
257 | local keyI = 0 |
258 | local useWrapperRot = false |
259 | while true do |
260 | local nodeKey = string.format(wrapAnimNodeKey..".key(%d)", keyI) |
261 | local wrapperRot = getXMLFloat(xmlFile, nodeKey.."#wrapperRot") |
262 | local wrapperTime = getXMLFloat(xmlFile, nodeKey.."#wrapperTime") |
263 | if wrapperRot == nil and wrapperTime == nil then |
264 | break |
265 | end |
266 | useWrapperRot = wrapperRot ~= nil |
267 | |
268 | local x, y, z = StringUtil.getVectorFromString(getXMLString(xmlFile, nodeKey.."#trans")) |
269 | local rx, ry, rz = StringUtil.getVectorFromString(getXMLString(xmlFile, nodeKey.."#rot")) |
270 | local sx, sy, sz = StringUtil.getVectorFromString(getXMLString(xmlFile, nodeKey.."#scale")) |
271 | |
272 | x = Utils.getNoNil(x, 0) |
273 | y = Utils.getNoNil(y, 0) |
274 | z = Utils.getNoNil(z, 0) |
275 | rx = math.rad(Utils.getNoNil(rx, 0)) |
276 | ry = math.rad(Utils.getNoNil(ry, 0)) |
277 | rz = math.rad(Utils.getNoNil(rz, 0)) |
278 | sx = Utils.getNoNil(sx, 1) |
279 | sy = Utils.getNoNil(sy, 1) |
280 | sz = Utils.getNoNil(sz, 1) |
281 | if wrapperRot ~= nil then |
282 | animCurve:addKeyframe({x, y, z, rx, ry, rz, sx,sy,sz, time = math.rad(wrapperRot)}) |
283 | else |
284 | animCurve:addKeyframe({x, y, z, rx, ry, rz, sx,sy,sz, time = wrapperTime}) |
285 | end |
286 | keyI = keyI +1 |
287 | end |
288 | if keyI > 0 then |
289 | local repeatWrapperRot = Utils.getNoNil(getXMLBool(xmlFile, wrapAnimNodeKey.."#repeatWrapperRot"), false) |
290 | local normalizeRotationOnBaleDrop = Utils.getNoNil(getXMLInt(xmlFile, wrapAnimNodeKey.."#normalizeRotationOnBaleDrop"), 0) |
291 | table.insert(wrapper.wrapAnimNodes, |
292 | {nodeId = nodeId, animCurve = animCurve, repeatWrapperRot = repeatWrapperRot, normalizeRotationOnBaleDrop = normalizeRotationOnBaleDrop, useWrapperRot = useWrapperRot}) |
293 | end |
294 | end |
295 | i = i + 1 |
296 | end |
297 | |
298 | |
299 | wrapper.wrapNodes = {} |
300 | i = 0 |
301 | while true do |
302 | local wrapNodeKey = string.format("%s.wrapNodes.wrapNode(%d)", baseKey, i) |
303 | if not hasXMLProperty(xmlFile, wrapNodeKey) then |
304 | break |
305 | end |
306 | local nodeId = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, wrapNodeKey.."#index"), self.i3dMappings) |
307 | local wrapVisibility = Utils.getNoNil(getXMLBool(xmlFile, wrapNodeKey.."#wrapVisibility"), false) |
308 | local emptyVisibility = Utils.getNoNil(getXMLBool(xmlFile, wrapNodeKey.."#emptyVisibility"), false) |
309 | if nodeId ~= nil and (wrapVisibility or emptyVisibility) then |
310 | local maxWrapperRot = getXMLFloat(xmlFile, wrapNodeKey.."#maxWrapperRot") |
311 | if maxWrapperRot == nil then |
312 | maxWrapperRot = math.huge |
313 | else |
314 | maxWrapperRot = math.rad(maxWrapperRot) |
315 | end |
316 | table.insert(wrapper.wrapNodes, {nodeId=nodeId, wrapVisibility=wrapVisibility, emptyVisibility=emptyVisibility, maxWrapperRot=maxWrapperRot}) |
317 | end |
318 | i = i + 1 |
319 | end |
320 | |
321 | wrapper.wrappingStateCurve = AnimCurve:new(linearInterpolator1) |
322 | i = 0 |
323 | while true do |
324 | local key2 = string.format("%s.wrappingState.key(%d)", baseKey, i) |
325 | if not hasXMLProperty(xmlFile, key2) then |
326 | break |
327 | end |
328 | |
329 | local t = getXMLFloat(xmlFile, key2.."#time") |
330 | local wrappingState = getXMLFloat(xmlFile, key2.."#wrappingState") |
331 | |
332 | wrapper.wrappingStateCurve:addKeyframe({wrappingState, time = t}) |
333 | i = i + 1 |
334 | end |
335 | |
336 | if self.isServer then |
337 | wrapper.collisions = {}; |
338 | i = 0; |
339 | while true do |
340 | local key2 = string.format("%s.wrappingCollisions.collision(%d)", baseKey, i); |
341 | if not hasXMLProperty(self.xmlFile, key2) then |
342 | break; |
343 | end; |
344 | |
345 | local node = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key2.."#node"), self.i3dMappings); |
346 | local activeCollisionMask = getXMLInt(self.xmlFile, key2.."#activeCollisionMask"); |
347 | local inActiveCollisionMask = getXMLInt(self.xmlFile, key2.."#inActiveCollisionMask"); |
348 | |
349 | table.insert(wrapper.collisions, {node=node, activeCollisionMask=activeCollisionMask, inActiveCollisionMask=inActiveCollisionMask}); |
350 | i = i + 1; |
351 | end |
352 | end |
353 | |
354 | local defaultText = (wrapper == self.spec_baleWrapper.roundBaleWrapper and "action_unloadRoundBale") or "action_unloadSquareBale" |
355 | wrapper.unloadBaleText = Utils.getNoNil(getXMLString(xmlFile, baseKey .. "#unloadBaleText"), defaultText) |
356 | |
357 | local fillTypesStr = getXMLString(self.xmlFile, baseKey .. "#skipWrappingFillTypes") |
358 | wrapper.skipUnsupportedBales = Utils.getNoNil(getXMLBool(self.xmlFile, baseKey.."#skipUnsupportedBales"), fillTypesStr ~= nil and fillTypesStr ~= "") |
359 | |
360 | if self.isClient then |
361 | wrapper.samples = {} |
362 | wrapper.samples.wrap = g_soundManager:loadSampleFromXML(self.xmlFile, baseKey..".sounds", "wrap", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
363 | wrapper.samples.start = g_soundManager:loadSampleFromXML(self.xmlFile, baseKey..".sounds", "start", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) |
364 | wrapper.samples.stop = g_soundManager:loadSampleFromXML(self.xmlFile, baseKey..".sounds", "stop", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) |
365 | wrapper.wrappingSoundEndTime = Utils.getNoNil(getXMLFloat(xmlFile, baseKey .. ".sounds#wrappingEndTime"), 1) |
366 | end |
367 | end |
onDeactivate
DescriptionCalled on deactivatingDefinition
onDeactivate()Code
1119 | function BaleWrapper:onDeactivate() |
1120 | local spec = self.spec_baleWrapper |
1121 | spec.showInvalidBaleWarning = false |
1122 | if self.isClient then |
1123 | for _, sample in pairs(spec.currentWrapper.samples) do |
1124 | g_soundManager:stopSample(sample) |
1125 | end |
1126 | end |
1127 | end |
onDelete
DescriptionCalled on deletingDefinition
onDelete()Code
405 | function BaleWrapper:onDelete() |
406 | local spec = self.spec_baleWrapper |
407 | |
408 | local baleId |
409 | if spec.currentWrapper.currentBale ~= nil then |
410 | baleId = spec.currentWrapper.currentBale |
411 | end |
412 | if spec.baleGrabber.currentBale ~= nil then |
413 | baleId = spec.baleGrabber.currentBale |
414 | end |
415 | if baleId ~= nil then |
416 | local bale = NetworkUtil.getObject(baleId) |
417 | if bale ~= nil then |
418 | if self.isReconfigurating == nil or not self.isReconfigurating then |
419 | -- unmount bale if wrapper is sold |
420 | bale:unmount() |
421 | else |
422 | -- delete bale if reloaded since a new bale is spawned on load |
423 | bale:delete() |
424 | end |
425 | end |
426 | end |
427 | |
428 | if self.isClient then |
429 | g_soundManager:deleteSamples(spec.roundBaleWrapper.samples) |
430 | g_soundManager:deleteSamples(spec.squareBaleWrapper.samples) |
431 | end |
432 | end |
onDraw
DescriptionCalled on drawDefinition
onDraw()Code
666 | function BaleWrapper:onDraw(isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
667 | if self.isClient then |
668 | local spec = self.spec_baleWrapper |
669 | if spec.showInvalidBaleWarning then |
670 | g_currentMission:showBlinkingWarning(g_i18n:getText("warning_baleNotSupported"), 500) |
671 | end |
672 | end |
673 | end |
onLoad
DescriptionCalled on loadingDefinition
onLoad(table savegame)Arguments
table | savegame | savegame |
92 | function BaleWrapper:onLoad(savegame) |
93 | local spec = self.spec_baleWrapper |
94 | |
95 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.wrapper", "vehicle.baleWrapper") --FS17 to FS19 |
96 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleGrabber", "vehicle.baleWrapper.grabber") --FS17 to FS19 |
97 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleWrapper.grabber#index", "vehicle.baleWrapper.grabber#node") --FS17 to FS19 |
98 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleWrapper.grabber#index", "vehicle.baleWrapper.grabber#node") --FS17 to FS19 |
99 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleWrapper.roundBaleWrapper#baleIndex", "vehicle.baleWrapper.roundBaleWrapper#baleNode") --FS17 to FS19 |
100 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleWrapper.roundBaleWrapper#wrapperIndex", "vehicle.baleWrapper.roundBaleWrapper#wrapperNode") --FS17 to FS19 |
101 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleWrapper.squareBaleWrapper#baleIndex", "vehicle.baleWrapper.squareBaleWrapper#baleNode") --FS17 to FS19 |
102 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleWrapper.squareBaleWrapper#wrapperIndex", "vehicle.baleWrapper.squareBaleWrapper#wrapperNode") --FS17 to FS19 |
103 | |
104 | local baseKey = "vehicle.baleWrapper" |
105 | |
106 | spec.roundBaleWrapper = {} |
107 | self:loadWrapperFromXML(spec.roundBaleWrapper, self.xmlFile, baseKey..".roundBaleWrapper") |
108 | |
109 | spec.squareBaleWrapper = {} |
110 | self:loadWrapperFromXML(spec.squareBaleWrapper, self.xmlFile, baseKey..".squareBaleWrapper") |
111 | |
112 | |
113 | spec.currentWrapper = {} |
114 | spec.currentWrapperFoldMinLimit = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey.."#foldMinLimit"), 0) |
115 | spec.currentWrapperFoldMaxLimit = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey.."#foldMaxLimit"), 1) |
116 | |
117 | |
118 | spec.currentWrapper = spec.roundBaleWrapper |
119 | self:updateWrapNodes(false, true, 0) |
120 | spec.currentWrapper = spec.squareBaleWrapper |
121 | self:updateWrapNodes(false, true, 0) |
122 | |
123 | spec.baleGrabber = {} |
124 | spec.baleGrabber.grabNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, baseKey..".grabber#node"), self.i3dMappings) |
125 | spec.baleGrabber.nearestDistance = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey..".grabber#nearestDistance"), 3.0) |
126 | |
127 | spec.baleToLoad = nil |
128 | spec.baleToMount = nil |
129 | spec.baleWrapperState = BaleWrapper.STATE_NONE |
130 | spec.grabberIsMoving = false |
131 | spec.hasBaleWrapper = true |
132 | spec.showInvalidBaleWarning = false |
133 | end |
onLoadFinished
DescriptionCalled after vehicle was added to phyiscsDefinition
onLoadFinished(table savegame)Arguments
table | savegame | savegame |
372 | function BaleWrapper:onLoadFinished(savegame) |
373 | local spec = self.spec_baleWrapper |
374 | |
375 | if spec.baleToLoad ~= nil then |
376 | local v = spec.baleToLoad |
377 | spec.baleToLoad = nil |
378 | local baleObject = Bale:new(self.isServer, self.isClient) |
379 | local x,y,z = unpack(v.translation) |
380 | local rx,ry,rz = unpack(v.rotation) |
381 | baleObject:load(v.filename, x,y,z,rx,ry,rz, v.fillLevel) |
382 | baleObject:setOwnerFarmId(self:getActiveFarm(), true) |
383 | baleObject:register() |
384 | |
385 | if baleObject.nodeId ~= nil and baleObject.nodeId ~= 0 then |
386 | self:doStateChange(BaleWrapper.CHANGE_GRAB_BALE, NetworkUtil.getObjectId(baleObject)) |
387 | self:doStateChange(BaleWrapper.CHANGE_DROP_BALE_AT_GRABBER) |
388 | |
389 | baleObject.baleValueScale = v.baleValueScale |
390 | local wrapperState = math.min(v.wrapperTime / spec.currentWrapper.animTime, 1) |
391 | baleObject:setWrappingState(wrapperState) |
392 | |
393 | self:doStateChange(BaleWrapper.CHANGE_WRAPPING_START) |
394 | spec.currentWrapper.currentTime = v.wrapperTime |
395 | |
396 | local wrappingTime = spec.currentWrapper.currentTime / spec.currentWrapper.animTime |
397 | self:setAnimationTime(spec.currentWrapper.animations["wrapBale"].animName, wrappingTime) |
398 | self:updateWrappingState(wrappingTime) |
399 | end |
400 | end |
401 | end |
onPostLoad
DescriptionDefinitiononPostLoad()Code
137 | function BaleWrapper:onPostLoad(savegame) |
138 | local spec = self.spec_baleWrapper |
139 | |
140 | if savegame ~= nil and not savegame.resetVehicles then |
141 | local filename = getXMLString(savegame.xmlFile, savegame.key..".baleWrapper#baleFileName") |
142 | if filename ~= nil then |
143 | filename = NetworkUtil.convertFromNetworkFilename(filename) |
144 | local wrapperTime = Utils.getNoNil(getXMLFloat(savegame.xmlFile, savegame.key..".baleWrapper#wrapperTime"), 0) |
145 | local baleValueScale = Utils.getNoNil(getXMLFloat(savegame.xmlFile, savegame.key..".baleWrapper#baleValueScale"), 1) |
146 | local fillLevel = getXMLFloat(savegame.xmlFile, savegame.key..".baleWrapper#fillLevel") |
147 | local translation = {0,0,0} |
148 | local rotation={0,0,0} |
149 | spec.baleToLoad = {filename=filename, translation=translation, rotation=rotation, fillLevel=fillLevel, wrapperTime=wrapperTime, baleValueScale=baleValueScale} |
150 | end |
151 | end |
152 | |
153 | if self.configurations["wrappingColor"] ~= nil then |
154 | ConfigurationUtil.setColor(self, self.xmlFile, "wrappingColor", self.configurations["wrappingColor"]) |
155 | end |
156 | end |
onReadStream
DescriptionCalled on client side on joinDefinition
onReadStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
461 | function BaleWrapper:onReadStream(streamId, connection) |
462 | if connection:getIsServer() then |
463 | local spec = self.spec_baleWrapper |
464 | |
465 | local isRoundBaleWrapper = streamReadBool(streamId) |
466 | if isRoundBaleWrapper then |
467 | spec.currentWrapper = spec.roundBaleWrapper |
468 | else |
469 | spec.currentWrapper = spec.squareBaleWrapper |
470 | end |
471 | |
472 | local wrapperState = streamReadUIntN(streamId, BaleWrapper.STATE_NUM_BITS) |
473 | if wrapperState >= BaleWrapper.STATE_MOVING_BALE_TO_WRAPPER then |
474 | local baleServerId |
475 | local isRoundBale |
476 | if wrapperState ~= BaleWrapper.STATE_WRAPPER_RESETTING_PLATFORM then |
477 | baleServerId = NetworkUtil.readNodeObjectId(streamId) |
478 | isRoundBale = streamReadBool(streamId) |
479 | end |
480 | |
481 | if wrapperState == BaleWrapper.STATE_MOVING_BALE_TO_WRAPPER then |
482 | self:doStateChange(BaleWrapper.CHANGE_GRAB_BALE, baleServerId) |
483 | AnimatedVehicle.updateAnimations(self, 99999999) |
484 | elseif wrapperState == BaleWrapper.STATE_MOVING_GRABBER_TO_WORK then |
485 | spec.baleGrabber.currentBale = baleServerId |
486 | |
487 | self:doStateChange(BaleWrapper.CHANGE_DROP_BALE_AT_GRABBER) |
488 | AnimatedVehicle.updateAnimations(self, 99999999) |
489 | |
490 | elseif wrapperState ~= BaleWrapper.STATE_WRAPPER_RESETTING_PLATFORM then |
491 | spec.currentWrapper = (isRoundBale and spec["roundBaleWrapper"]) or spec["squareBaleWrapper"] |
492 | |
493 | local attachNode = spec.currentWrapper.baleNode |
494 | spec.baleToMount = {serverId=baleServerId, linkNode=attachNode, trans={0,0,0}, rot={0,0,0} } |
495 | self:updateWrapNodes(true, false, 0) |
496 | spec.currentWrapper.currentBale = baleServerId |
497 | |
498 | if wrapperState == BaleWrapper.STATE_WRAPPER_WRAPPING_BALE then |
499 | local wrapperTime = streamReadFloat32(streamId) |
500 | spec.currentWrapper.currentTime = wrapperTime |
501 | self:updateWrappingState(spec.currentWrapper.currentTime / spec.currentWrapper.animTime, true) |
502 | else |
503 | spec.currentWrapper.currentTime = spec.currentWrapper.animTime |
504 | self:updateWrappingState(1, true) |
505 | |
506 | self:doStateChange(BaleWrapper.CHANGE_WRAPPING_BALE_FINSIHED) |
507 | AnimatedVehicle.updateAnimations(self, 99999999) |
508 | if wrapperState >= BaleWrapper.STATE_WRAPPER_DROPPING_BALE then |
509 | self:doStateChange(BaleWrapper.CHANGE_WRAPPER_START_DROP_BALE) |
510 | AnimatedVehicle.updateAnimations(self, 99999999) |
511 | end |
512 | end |
513 | else |
514 | -- simply set the state but do nothing else |
515 | spec.baleWrapperState = BaleWrapper.STATE_WRAPPER_RESETTING_PLATFORM |
516 | end |
517 | end |
518 | end |
519 | end |
onRegisterActionEvents
DescriptionDefinitiononRegisterActionEvents()Code
1103 | function BaleWrapper:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection) |
1104 | if self.isClient then |
1105 | |
1106 | local spec = self.spec_baleWrapper |
1107 | self:clearActionEventsTable(spec.actionEvents) |
1108 | |
1109 | if isActiveForInputIgnoreSelection then |
1110 | local _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.IMPLEMENT_EXTRA3, self, BaleWrapper.actionEventEmpty, true, false, false, true, nil) |
1111 | g_inputBinding:setActionEventText(actionEventId, g_i18n:getText(spec.currentWrapper.unloadBaleText, self.customEnvironment)) |
1112 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_HIGH) |
1113 | end |
1114 | end |
1115 | end |
onUpdate
DescriptionCalled on updateDefinition
onUpdate(float dt, boolean isActiveForInput, boolean isSelected)Arguments
float | dt | time since last call in ms |
boolean | isActiveForInput | true if vehicle is active for input |
boolean | isSelected | true if vehicle is selected |
557 | function BaleWrapper:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
558 | local spec = self.spec_baleWrapper |
559 | |
560 | if self.firstTimeRun then |
561 | if spec.baleToMount ~= nil then |
562 | local bale = NetworkUtil.getObject(spec.baleToMount.serverId) |
563 | if bale ~= nil then |
564 | local x,y,z = unpack(spec.baleToMount.trans) |
565 | local rx,ry,rz = unpack(spec.baleToMount.rot) |
566 | bale:mount(self, spec.baleToMount.linkNode, x,y,z, rx,ry,rz) |
567 | spec.baleToMount = nil |
568 | |
569 | if spec.baleWrapperState == BaleWrapper.STATE_MOVING_BALE_TO_WRAPPER then |
570 | self:playMoveToWrapper(bale) |
571 | end |
572 | end |
573 | end |
574 | end |
575 | |
576 | if spec.baleWrapperState == BaleWrapper.STATE_WRAPPER_WRAPPING_BALE then |
577 | local wrapper = spec.currentWrapper |
578 | |
579 | wrapper.currentTime = wrapper.currentTime + dt |
580 | local wrappingTime = wrapper.currentTime / wrapper.animTime |
581 | self:updateWrappingState(wrappingTime) |
582 | self:raiseActive() |
583 | |
584 | if self.isClient then |
585 | if wrapper.wrappingSoundEndTime <= wrappingTime then |
586 | if g_soundManager:getIsSamplePlaying(wrapper.samples.wrap) then |
587 | g_soundManager:stopSample(wrapper.samples.wrap) |
588 | g_soundManager:playSample(wrapper.samples.stop) |
589 | end |
590 | else |
591 | if not g_soundManager:getIsSamplePlaying(wrapper.samples.wrap) then |
592 | g_soundManager:playSample(wrapper.samples.wrap) |
593 | end |
594 | end |
595 | end |
596 | end |
597 | end |
onUpdateTick
DescriptionCalled on update tickDefinition
onUpdateTick(float dt, boolean isActiveForInput, boolean isSelected)Arguments
float | dt | time since last call in ms |
boolean | isActiveForInput | true if vehicle is active for input |
boolean | isSelected | true if vehicle is selected |
604 | function BaleWrapper:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
605 | local spec = self.spec_baleWrapper |
606 | |
607 | spec.showInvalidBaleWarning = false |
608 | |
609 | if self:allowsGrabbingBale() then |
610 | if spec.baleGrabber.grabNode ~= nil and spec.baleGrabber.currentBale == nil then |
611 | -- find nearest bale |
612 | local nearestBale, nearestBaleType = BaleWrapper.getBaleInRange(self, spec.baleGrabber.grabNode, spec.baleGrabber.nearestDistance) |
613 | if nearestBale ~= nil then |
614 | if self.isServer and (nearestBaleType ~= nil or self:getIsBaleFillTypeSkiped(nearestBale)) then |
615 | self:pickupWrapperBale(nearestBale, nearestBaleType) |
616 | else |
617 | if spec.lastDroppedBale ~= nearestBale then |
618 | spec.showInvalidBaleWarning = true |
619 | end |
620 | end |
621 | end |
622 | end |
623 | end |
624 | if self.isServer then |
625 | if spec.baleWrapperState ~= BaleWrapper.STATE_NONE then |
626 | if spec.baleWrapperState == BaleWrapper.STATE_MOVING_BALE_TO_WRAPPER then |
627 | if not self:getIsAnimationPlaying(spec.currentWrapper.animations["moveToWrapper"].animName) then |
628 | g_server:broadcastEvent(BaleWrapperStateEvent:new(self, BaleWrapper.CHANGE_DROP_BALE_AT_GRABBER), true, nil, self) |
629 | end |
630 | elseif spec.baleWrapperState == BaleWrapper.STATE_MOVING_GRABBER_TO_WORK then |
631 | if not self:getIsAnimationPlaying(spec.currentWrapper.animations["moveToWrapper"].animName) then |
632 | local bale = NetworkUtil.getObject(spec.currentWrapper.currentBale) |
633 | if bale ~= nil and not bale.supportsWrapping then |
634 | g_server:broadcastEvent(BaleWrapperStateEvent:new(self, BaleWrapper.CHANGE_WRAPPER_START_DROP_BALE), true, nil, self) |
635 | else |
636 | g_server:broadcastEvent(BaleWrapperStateEvent:new(self, BaleWrapper.CHANGE_WRAPPING_START), true, nil, self) |
637 | end |
638 | end |
639 | elseif spec.baleWrapperState == BaleWrapper.STATE_WRAPPER_DROPPING_BALE then |
640 | if not self:getIsAnimationPlaying(spec.currentWrapper.animations["dropFromWrapper"].animName) then |
641 | g_server:broadcastEvent(BaleWrapperStateEvent:new(self, BaleWrapper.CHANGE_WRAPPER_BALE_DROPPED), true, nil, self) |
642 | end |
643 | elseif spec.baleWrapperState == BaleWrapper.STATE_WRAPPER_RESETTING_PLATFORM then |
644 | if not self:getIsAnimationPlaying(spec.currentWrapper.animations["resetAfterDrop"].animName) then |
645 | g_server:broadcastEvent(BaleWrapperStateEvent:new(self, BaleWrapper.CHANGE_WRAPPER_PLATFORM_RESET), true, nil, self) |
646 | end |
647 | end |
648 | end |
649 | end |
650 | |
651 | -- update action event visibility and text |
652 | local actionEvent = spec.actionEvents[InputAction.IMPLEMENT_EXTRA3] |
653 | if actionEvent ~= nil then |
654 | g_inputBinding:setActionEventActive(actionEvent.actionEventId, spec.baleWrapperState == BaleWrapper.STATE_WRAPPER_FINSIHED) |
655 | g_inputBinding:setActionEventText(actionEvent.actionEventId, g_i18n:getText(spec.currentWrapper.unloadBaleText, self.customEnvironment)) |
656 | end |
657 | |
658 | if spec.setWrappingStateFinished then |
659 | g_server:broadcastEvent(BaleWrapperStateEvent:new(self, BaleWrapper.CHANGE_WRAPPING_BALE_FINSIHED), true, nil, self) |
660 | spec.setWrappingStateFinished = false |
661 | end |
662 | end |
onWriteStream
DescriptionCalled on server side on joinDefinition
onWriteStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
525 | function BaleWrapper:onWriteStream(streamId, connection) |
526 | if not connection:getIsServer() then |
527 | local spec = self.spec_baleWrapper |
528 | |
529 | streamWriteBool(streamId, spec.currentWrapper == spec.roundBaleWrapper) |
530 | |
531 | local wrapperState = spec.baleWrapperState |
532 | streamWriteUIntN(streamId, wrapperState, BaleWrapper.STATE_NUM_BITS) |
533 | |
534 | if wrapperState >= BaleWrapper.STATE_MOVING_BALE_TO_WRAPPER and wrapperState ~= BaleWrapper.STATE_WRAPPER_RESETTING_PLATFORM then |
535 | local bale |
536 | if wrapperState == BaleWrapper.STATE_MOVING_BALE_TO_WRAPPER then |
537 | NetworkUtil.writeNodeObjectId(streamId, spec.baleGrabber.currentBale) |
538 | bale = NetworkUtil.getObject(spec.baleGrabber.currentBale) |
539 | else |
540 | NetworkUtil.writeNodeObjectId(streamId, spec.currentWrapper.currentBale) |
541 | bale = NetworkUtil.getObject(spec.currentWrapper.currentBale) |
542 | end |
543 | |
544 | streamWriteBool(streamId, (bale or {}).baleDiameter ~= nil) |
545 | end |
546 | if wrapperState == BaleWrapper.STATE_WRAPPER_WRAPPING_BALE then |
547 | streamWriteFloat32(streamId, spec.currentWrapper.currentTime) |
548 | end |
549 | end |
550 | end |
pickupWrapperBale
DescriptionPickup bale to wrapDefinition
pickupWrapperBale(table bale, integer baleType)Arguments
table | bale | bale to pickup |
integer | baleType | type of bale |
992 | function BaleWrapper:pickupWrapperBale(bale, baleType) |
993 | if baleType ~= nil and bale.i3dFilename ~= baleType.wrapperBaleFilename then |
994 | local x,y,z = getWorldTranslation(bale.nodeId) |
995 | local rx,ry,rz = getWorldRotation(bale.nodeId) |
996 | local fillLevel = bale.fillLevel |
997 | local baleValueScale = bale.baleValueScale |
998 | local baleFarm = bale:getOwnerFarmId() |
999 | bale:delete() |
1000 | |
1001 | bale = Bale:new(self.isServer, self.isClient) |
1002 | bale:load(baleType.wrapperBaleFilename, x,y,z, rx,ry,rz, fillLevel) |
1003 | bale.baleValueScale = baleValueScale |
1004 | bale:setOwnerFarmId(baleFarm, true) |
1005 | bale:register() |
1006 | end |
1007 | |
1008 | -- found bale |
1009 | g_server:broadcastEvent(BaleWrapperStateEvent:new(self, BaleWrapper.CHANGE_GRAB_BALE, NetworkUtil.getObjectId(bale)), true, nil, self) |
1010 | end |
playMoveToWrapper
DescriptionPlay move to wrapper animationDefinition
playMoveToWrapper(table bale)Arguments
table | bale | bale to move |
805 | function BaleWrapper:playMoveToWrapper(bale) |
806 | local spec = self.spec_baleWrapper |
807 | |
808 | spec.currentWrapper = spec.roundBaleWrapper |
809 | if bale.baleDiameter == nil then |
810 | spec.currentWrapper = spec.squareBaleWrapper |
811 | end |
812 | |
813 | if spec.currentWrapper.animations["moveToWrapper"].animName ~= nil then |
814 | self:playAnimation(spec.currentWrapper.animations["moveToWrapper"].animName, spec.currentWrapper.animations["moveToWrapper"].animSpeed, nil, true) |
815 | end |
816 | end |
prerequisitesPresent
DescriptionChecks if all prerequisite specializations are loadedDefinition
prerequisitesPresent(table specializations)Arguments
table | specializations | specializations |
boolean | hasPrerequisite | true if all prerequisite specializations are loaded |
41 | function BaleWrapper.prerequisitesPresent(specializations) |
42 | return SpecializationUtil.hasSpecialization(AnimatedVehicle, specializations) |
43 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
69 | function BaleWrapper.registerEventListeners(vehicleType) |
70 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", BaleWrapper) |
71 | SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", BaleWrapper) |
72 | SpecializationUtil.registerEventListener(vehicleType, "onLoadFinished", BaleWrapper) |
73 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", BaleWrapper) |
74 | SpecializationUtil.registerEventListener(vehicleType, "onReadStream", BaleWrapper) |
75 | SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", BaleWrapper) |
76 | SpecializationUtil.registerEventListener(vehicleType, "onUpdate", BaleWrapper) |
77 | SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", BaleWrapper) |
78 | SpecializationUtil.registerEventListener(vehicleType, "onDraw", BaleWrapper) |
79 | SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", BaleWrapper) |
80 | SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", BaleWrapper) |
81 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
47 | function BaleWrapper.registerFunctions(vehicleType) |
48 | SpecializationUtil.registerFunction(vehicleType, "loadWrapperFromXML", BaleWrapper.loadWrapperFromXML) |
49 | |
50 | SpecializationUtil.registerFunction(vehicleType, "allowsGrabbingBale", BaleWrapper.allowsGrabbingBale) |
51 | SpecializationUtil.registerFunction(vehicleType, "pickupWrapperBale", BaleWrapper.pickupWrapperBale) |
52 | SpecializationUtil.registerFunction(vehicleType, "getIsBaleFillTypeSkiped", BaleWrapper.getIsBaleFillTypeSkiped) |
53 | SpecializationUtil.registerFunction(vehicleType, "getWrapperBaleType", BaleWrapper.getWrapperBaleType) |
54 | SpecializationUtil.registerFunction(vehicleType, "updateWrappingState", BaleWrapper.updateWrappingState) |
55 | SpecializationUtil.registerFunction(vehicleType, "doStateChange", BaleWrapper.doStateChange) |
56 | SpecializationUtil.registerFunction(vehicleType, "updateWrapNodes", BaleWrapper.updateWrapNodes) |
57 | SpecializationUtil.registerFunction(vehicleType, "playMoveToWrapper", BaleWrapper.playMoveToWrapper) |
58 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
62 | function BaleWrapper.registerOverwrittenFunctions(vehicleType) |
63 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsFoldAllowed", BaleWrapper.getIsFoldAllowed) |
64 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", BaleWrapper.getCanBeSelected) |
65 | end |
saveToXMLFile
DescriptionDefinitionsaveToXMLFile()Code
436 | function BaleWrapper:saveToXMLFile(xmlFile, key, usedModNames) |
437 | local spec = self.spec_baleWrapper |
438 | |
439 | local baleServerId = spec.baleGrabber.currentBale |
440 | if baleServerId == nil then |
441 | baleServerId = spec.currentWrapper.currentBale |
442 | end |
443 | |
444 | if baleServerId ~= nil then |
445 | local bale = NetworkUtil.getObject(baleServerId) |
446 | if bale ~= nil then |
447 | local fillLevel = bale:getFillLevel() |
448 | local baleValueScale = bale.baleValueScale |
449 | setXMLString(xmlFile, key.."#baleFileName", HTMLUtil.encodeToHTML(NetworkUtil.convertToNetworkFilename(bale.i3dFilename))) |
450 | setXMLFloat(xmlFile, key.."#fillLevel", fillLevel) |
451 | setXMLFloat(xmlFile, key.."#wrapperTime", spec.currentWrapper.currentTime) |
452 | setXMLFloat(xmlFile, key.."#baleValueScale", baleValueScale) |
453 | end |
454 | end |
455 | end |
updateWrapNodes
DescriptionUpdate bale wrap nodesDefinition
updateWrapNodes(boolean isWrapping, boolean isEmpty, float t, float wrapperRot)Arguments
boolean | isWrapping | is wrapping |
boolean | isEmpty | is empty |
float | t | animation time |
float | wrapperRot | rotation of wrapper |
700 | function BaleWrapper:updateWrapNodes(isWrapping, isEmpty, t, wrapperRot) |
701 | local spec = self.spec_baleWrapper |
702 | |
703 | if wrapperRot == nil then |
704 | wrapperRot = 0 |
705 | end |
706 | |
707 | for _, wrapNode in pairs(spec.currentWrapper.wrapNodes) do |
708 | local doShow = true |
709 | if wrapNode.maxWrapperRot ~= nil then |
710 | doShow = wrapperRot < wrapNode.maxWrapperRot |
711 | end |
712 | setVisibility(wrapNode.nodeId, doShow and ((isWrapping and wrapNode.wrapVisibility) or (isEmpty and wrapNode.emptyVisibility))) |
713 | end |
714 | |
715 | if isWrapping then |
716 | local wrapperRotRepeat = MathUtil.sign(wrapperRot) * (wrapperRot % math.pi) |
717 | if wrapperRotRepeat < 0 then |
718 | wrapperRotRepeat = wrapperRotRepeat + math.pi |
719 | end |
720 | |
721 | for _,wrapAnimNode in pairs(spec.currentWrapper.wrapAnimNodes) do |
722 | local v |
723 | if wrapAnimNode.useWrapperRot then |
724 | local rot = wrapperRot |
725 | if wrapAnimNode.repeatWrapperRot then |
726 | rot = wrapperRotRepeat |
727 | end |
728 | v = wrapAnimNode.animCurve:get(rot) |
729 | else |
730 | v = wrapAnimNode.animCurve:get(t) |
731 | end |
732 | if v ~= nil then |
733 | setTranslation(wrapAnimNode.nodeId, v[1], v[2], v[3]) |
734 | setRotation(wrapAnimNode.nodeId, v[4], v[5], v[6]) |
735 | setScale(wrapAnimNode.nodeId, v[7], v[8], v[9]) |
736 | end |
737 | end |
738 | else |
739 | if not isEmpty then |
740 | for _,wrapAnimNode in pairs(spec.currentWrapper.wrapAnimNodes) do |
741 | if wrapAnimNode.normalizeRotationOnBaleDrop ~= 0 then |
742 | local rot = { getRotation(wrapAnimNode.nodeId) } |
743 | for i=1,3 do |
744 | rot[i] = wrapAnimNode.normalizeRotationOnBaleDrop * MathUtil.sign(rot[i]) * ( rot[i] % (2*math.pi) ) |
745 | end |
746 | setRotation(wrapAnimNode.nodeId, rot[1],rot[2],rot[3]) |
747 | end |
748 | end |
749 | end |
750 | end |
751 | end |
updateWrappingState
DescriptionUpdate wrapping stateDefinition
updateWrappingState(float t, boolean noEventSend)Arguments
float | t | animation time |
boolean | noEventSend | no event send |
757 | function BaleWrapper:updateWrappingState(t, noEventSend) |
758 | local spec = self.spec_baleWrapper |
759 | |
760 | t = math.min(t, 1) |
761 | local wrapperRot = 0 |
762 | if spec.currentWrapper.animCurve ~= nil then |
763 | local v = spec.currentWrapper.animCurve:get(t) |
764 | if v ~= nil then |
765 | setRotation(spec.currentWrapper.baleNode, v[1]%(math.pi*2), v[2]%(math.pi*2), v[3]%(math.pi*2)) |
766 | setRotation(spec.currentWrapper.wrapperNode, v[4]%(math.pi*2), v[5]%(math.pi*2), v[6]%(math.pi*2)) |
767 | wrapperRot = v[3 + spec.currentWrapper.wrapperRotAxis] |
768 | elseif spec.currentWrapper.animations["wrapBale"].animName ~= nil then |
769 | t = self:getAnimationTime(spec.currentWrapper.animations["wrapBale"].animName) |
770 | end |
771 | if spec.currentWrapper.currentBale ~= nil then |
772 | local bale = NetworkUtil.getObject(spec.currentWrapper.currentBale) |
773 | if bale ~= nil then |
774 | if not self:getIsBaleFillTypeSkiped(bale) then |
775 | if self.isServer then |
776 | local wrappingState = t |
777 | if table.getn(spec.currentWrapper.wrappingStateCurve.keyframes) > 0 then |
778 | wrappingState = spec.currentWrapper.wrappingStateCurve:get(t) |
779 | end |
780 | bale:setWrappingState(wrappingState) |
781 | end |
782 | |
783 | if bale.setColor ~= nil then |
784 | local color = ConfigurationUtil.getColorByConfigId(self, "wrappingColor") |
785 | if color ~= nil then |
786 | local r, g, b, a = unpack(color) |
787 | bale:setColor(r, g, b, a) |
788 | end |
789 | end |
790 | end |
791 | end |
792 | end |
793 | end |
794 | self:updateWrapNodes(t > 0, false, t, wrapperRot) |
795 | if t == 1 then |
796 | if self.isServer and spec.baleWrapperState == BaleWrapper.STATE_WRAPPER_WRAPPING_BALE and not noEventSend then |
797 | g_server:broadcastEvent(BaleWrapperStateEvent:new(self, BaleWrapper.CHANGE_WRAPPING_BALE_FINSIHED), true, nil, self) |
798 | end |
799 | end |
800 | end |