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
AttacherJointControl
DescriptionSpecialization to steplessly control the height of an attacherJointFunctions
- actionEventAttacherJointControl
- actionEventAttacherJointControlSetPoint
- controlAttacherJoint
- controlAttacherJointHeight
- controlAttacherJointTilt
- getCanBeSelected
- getControlAttacherJointDirection
- getIsAttacherJointControlDampingAllowed
- getLoweringActionEventState
- initSpecialization
- loadInputAttacherJoint
- onDelete
- onLoad
- onPostAttach
- onPreDetach
- onReadStream
- onReadUpdateStream
- onRegisterActionEvents
- onUpdate
- onWriteStream
- onWriteUpdateStream
- prerequisitesPresent
- registerEventListeners
- registerFunctions
- registerLoweringActionEvent
- registerOverwrittenFunctions
actionEventAttacherJointControl
DescriptionDefinitionactionEventAttacherJointControl()Code
577 | function AttacherJointControl.actionEventAttacherJointControl(self, actionName, inputValue, callbackState, isAnalog) |
578 | if math.abs(inputValue) > 0 then |
579 | local spec = self.spec_attacherJointControl |
580 | local control = spec.nameToControl[actionName] |
581 | |
582 | -- multiply by 0.025 to have to same speed as in fs17 |
583 | local changedAlpha = inputValue * control.mouseSpeedFactor * 0.025 |
584 | if control.invertAxis then |
585 | changedAlpha = -changedAlpha |
586 | end |
587 | |
588 | self:controlAttacherJoint(control, control.moveAlpha + changedAlpha, false) |
589 | spec.heightTargetAlpha = -1 |
590 | end |
591 | end |
actionEventAttacherJointControlSetPoint
DescriptionDefinitionactionEventAttacherJointControlSetPoint()Code
595 | function AttacherJointControl.actionEventAttacherJointControlSetPoint(self, actionName, inputValue, callbackState, isAnalog) |
596 | local spec = self.spec_attacherJointControl |
597 | if spec.jointDesc ~= nil then |
598 | if self:getControlAttacherJointDirection() then |
599 | spec.heightTargetAlpha = spec.jointDesc.lowerAlpha |
600 | else |
601 | spec.heightTargetAlpha = spec.jointDesc.upperAlpha |
602 | end |
603 | |
604 | spec.nextHeightDampingUpdateTime = g_time + spec.jointDesc.moveTime |
605 | end |
606 | end |
controlAttacherJoint
DescriptionUpdates attacher joint move alpha and update joint frameDefinition
controlAttacherJoint(table control, float moveAlpha)Arguments
table | control | control |
float | moveAlpha | move alpha |
341 | function AttacherJointControl:controlAttacherJoint(control, moveAlpha, automaticControl, noEventSend) |
342 | local spec = self.spec_attacherJointControl |
343 | local jointDesc = spec.jointDesc |
344 | |
345 | if self.isServer and jointDesc ~= nil then |
346 | moveAlpha = control.func(self, moveAlpha) |
347 | |
348 | local attacherVehicle = self:getAttacherVehicle() |
349 | attacherVehicle:updateAttacherJointRotation(jointDesc, self) |
350 | if jointDesc.jointIndex ~= 0 then |
351 | setJointFrame(jointDesc.jointIndex, 0, jointDesc.jointTransform) |
352 | end |
353 | end |
354 | |
355 | spec.lastMoveTime = g_time |
356 | |
357 | if not automaticControl then |
358 | spec.nextHeightDampingUpdateTime = g_time + 100 |
359 | control.moveAlphaLastManual = control.moveAlpha |
360 | end |
361 | |
362 | control.moveAlpha = math.min(math.max(moveAlpha, 0), 1) |
363 | |
364 | if noEventSend == nil or not noEventSend then |
365 | if math.abs(control.moveAlphaSent-moveAlpha) > 1 / AttacherJointControl.ALPHA_MAX_VALUE then |
366 | control.moveAlphaSent = moveAlpha |
367 | |
368 | if not self.isServer then |
369 | self:raiseDirtyFlags(spec.dirtyFlagClient) |
370 | else |
371 | self:raiseDirtyFlags(spec.dirtyFlagServer) |
372 | end |
373 | end |
374 | else |
375 | control.moveAlphaSent = moveAlpha |
376 | end |
377 | end |
controlAttacherJointHeight
DescriptionUpdates attacher joint height by given mve alpha valueDefinition
controlAttacherJointHeight(float moveAlpha)Arguments
float | moveAlpha | move alpha |
float | moveAlpha | limited move alpha |
383 | function AttacherJointControl:controlAttacherJointHeight(moveAlpha) |
384 | local spec = self.spec_attacherJointControl |
385 | local jointDesc = spec.jointDesc |
386 | |
387 | if moveAlpha == nil then |
388 | moveAlpha = jointDesc.moveAlpha |
389 | end |
390 | |
391 | moveAlpha = MathUtil.clamp(moveAlpha, jointDesc.upperAlpha, jointDesc.lowerAlpha) |
392 | self:updateAttacherJointRotationNodes(jointDesc, moveAlpha) |
393 | |
394 | spec.lastHeightAlpha = moveAlpha |
395 | |
396 | return moveAlpha |
397 | end |
controlAttacherJointTilt
DescriptionUpdates attacher joint tilt by given mve alpha valueDefinition
controlAttacherJointTilt(float moveAlpha)Arguments
float | moveAlpha | move alpha |
float | moveAlpha | limited move alpha |
403 | function AttacherJointControl:controlAttacherJointTilt(moveAlpha) |
404 | local spec = self.spec_attacherJointControl |
405 | |
406 | if moveAlpha == nil then |
407 | moveAlpha = 0.5 |
408 | end |
409 | |
410 | moveAlpha = MathUtil.clamp(moveAlpha, 0, 1) |
411 | local angle = spec.maxTiltAngle * -(moveAlpha - 0.5) |
412 | |
413 | spec.jointDesc.upperRotationOffset = spec.jointDesc.upperRotationOffsetBackup + angle |
414 | spec.jointDesc.lowerRotationOffset = spec.jointDesc.lowerRotationOffsetBackup + angle |
415 | |
416 | return moveAlpha |
417 | end |
getCanBeSelected
DescriptionDefinitiongetCanBeSelected()Code
501 | function AttacherJointControl:getCanBeSelected(superFunc) |
502 | return true |
503 | end |
getControlAttacherJointDirection
DescriptionReturns direction boolean for lifting and lowering the implement by button pressDefinition
getControlAttacherJointDirection()Return Values
boolean | direction | direction |
422 | function AttacherJointControl:getControlAttacherJointDirection() |
423 | local spec = self.spec_attacherJointControl |
424 | if spec.heightTargetAlpha ~= -1 then |
425 | return spec.heightTargetAlpha == spec.jointDesc.upperAlpha |
426 | end |
427 | |
428 | local lastAlpha = spec.heightController.moveAlpha |
429 | return math.abs(lastAlpha - spec.jointDesc.lowerAlpha) > math.abs(lastAlpha - spec.jointDesc.upperAlpha) |
430 | end |
getIsAttacherJointControlDampingAllowed
DescriptionReturns if damping is allowedDefinition
getIsAttacherJointControlDampingAllowed()Return Values
boolean | allowed | allowed |
435 | function AttacherJointControl:getIsAttacherJointControlDampingAllowed() |
436 | local attacherVehicle = self:getAttacherVehicle() |
437 | if attacherVehicle:getLastSpeed() < 0.5 then |
438 | return false |
439 | end |
440 | |
441 | if self.movingDirection <= 0 then |
442 | return false |
443 | end |
444 | |
445 | return true |
446 | end |
getLoweringActionEventState
DescriptionDefinitiongetLoweringActionEventState()Code
479 | function AttacherJointControl:getLoweringActionEventState(superFunc) |
480 | local spec = self.spec_attacherJointControl |
481 | if spec.heightController then |
482 | local showText = spec.jointDesc ~= nil |
483 | |
484 | local text |
485 | if showText then |
486 | if self:getControlAttacherJointDirection() then |
487 | text = string.format(g_i18n:getText("action_lowerOBJECT"), self.typeDesc) |
488 | else |
489 | text = string.format(g_i18n:getText("action_liftOBJECT"), self.typeDesc) |
490 | end |
491 | end |
492 | |
493 | return showText, text |
494 | end |
495 | |
496 | return superFunc(self) |
497 | end |
initSpecialization
DescriptionDefinitioninitSpecialization()Code
26 | function AttacherJointControl.initSpecialization() |
27 | local schema = Vehicle.xmlSchema |
28 | schema:setXMLSpecializationType("AttacherJointControl") |
29 | |
30 | schema:register(XMLValueType.ANGLE, "vehicle.attacherJointControl#maxTiltAngle", "Max tilt angle", 25) |
31 | schema:register(XMLValueType.BOOL, "vehicle.attacherJointControl#supportsDamping", "Supports damping of Y axis", false) |
32 | schema:register(XMLValueType.FLOAT, "vehicle.attacherJointControl#dampingOffset", "Distance from attacher joint to damping reference point (m)", 2) |
33 | schema:register(XMLValueType.STRING, "vehicle.attacherJointControl.control(?)#controlFunction", "Control script function (controlAttacherJointHeight or controlAttacherJointTilt)") |
34 | schema:register(XMLValueType.STRING, "vehicle.attacherJointControl.control(?)#controlAxis", "Name of input action") |
35 | schema:register(XMLValueType.STRING, "vehicle.attacherJointControl.control(?)#iconName", "Name of icon") |
36 | schema:register(XMLValueType.BOOL, "vehicle.attacherJointControl.control(?)#invertControlAxis", "Invert control axis", false) |
37 | schema:register(XMLValueType.FLOAT, "vehicle.attacherJointControl.control(?)#mouseSpeedFactor", "Mouse speed factor", 1) |
38 | |
39 | SoundManager.registerSampleXMLPaths(schema, "vehicle.attacherJointControl.sounds", "hydraulic") |
40 | |
41 | schema:register(XMLValueType.BOOL, Attachable.INPUT_ATTACHERJOINT_XML_KEY .. "#isControllable", "Is controllable", false) |
42 | schema:register(XMLValueType.BOOL, Attachable.INPUT_ATTACHERJOINT_CONFIG_XML_KEY .. "#isControllable", "Is controllable", false) |
43 | |
44 | schema:setXMLSpecializationType() |
45 | end |
loadInputAttacherJoint
DescriptionCalled on loadingDefinition
loadInputAttacherJoint(table savegame)Arguments
table | savegame | savegame |
451 | function AttacherJointControl:loadInputAttacherJoint(superFunc, xmlFile, key, inputAttacherJoint, i) |
452 | if not superFunc(self, xmlFile, key, inputAttacherJoint, i) then |
453 | return false |
454 | end |
455 | |
456 | inputAttacherJoint.isControllable = xmlFile:getValue(key .. "#isControllable", false) |
457 | |
458 | return true |
459 | end |
onDelete
DescriptionDefinitiononDelete()Code
180 | function AttacherJointControl:onDelete() |
181 | local spec = self.spec_attacherJointControl |
182 | if self.isClient and spec.samples ~= nil then |
183 | g_soundManager:deleteSample(spec.samples.hydraulic) |
184 | end |
185 | end |
onLoad
DescriptionCalled on loadingDefinition
onLoad(table savegame)Arguments
table | savegame | savegame |
84 | function AttacherJointControl:onLoad(savegame) |
85 | local spec = self.spec_attacherJointControl |
86 | |
87 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.attacherJointControl.control1", "vehicle.attacherJointControl.control with #controlFunction 'controlAttacherJointHeight'") -- FS17 |
88 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.attacherJointControl.control2", "vehicle.attacherJointControl.control with #controlFunction 'controlAttacherJointTilt'") -- FS17 |
89 | |
90 | local baseKey = "vehicle.attacherJointControl" |
91 | spec.maxTiltAngle = self.xmlFile:getValue(baseKey .. "#maxTiltAngle", 25) |
92 | spec.heightTargetAlpha = -1 |
93 | |
94 | spec.supportsDamping = self.xmlFile:getValue(baseKey .. "#supportsDamping", false) |
95 | spec.dampingOffset = self.xmlFile:getValue(baseKey .. "#dampingOffset", 2) |
96 | spec.nextHeightDampingUpdateTime = 0 |
97 | |
98 | spec.controls = {} |
99 | spec.nameToControl = {} |
100 | local i = 0 |
101 | while true do |
102 | local key = string.format("%s.control(%d)", baseKey, i) |
103 | if not self.xmlFile:hasProperty(key) then |
104 | break |
105 | end |
106 | |
107 | local control = {} |
108 | |
109 | local controlFunc = self.xmlFile:getValue(key .. "#controlFunction") |
110 | if controlFunc ~= nil and self[controlFunc] ~= nil then |
111 | control.func = self[controlFunc] |
112 | |
113 | if control.func == self.controlAttacherJointHeight then |
114 | spec.heightController = control |
115 | end |
116 | |
117 | if control.func == self.controlAttacherJointTilt then |
118 | spec.tiltController = control |
119 | end |
120 | else |
121 | Logging.xmlWarning(self.xmlFile, "Unknown control function '%s' for attacher joint control '%s'", tostring(controlFunc), key) |
122 | break |
123 | end |
124 | |
125 | local actionBindingName = self.xmlFile:getValue(key .. "#controlAxis") |
126 | if actionBindingName ~= nil and InputAction[actionBindingName] ~= nil then |
127 | control.controlAction = InputAction[actionBindingName] |
128 | else |
129 | Logging.xmlWarning(self.xmlFile, "Unknown control axis '%s' for attacher joint control '%s'", tostring(actionBindingName), key) |
130 | break |
131 | end |
132 | |
133 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, key.."#controlAxisIcon", key.."#iconName") --FS17 to FS19 |
134 | |
135 | local iconName = self.xmlFile:getValue(key .. "#iconName", "") |
136 | if InputHelpElement.AXIS_ICON[iconName] == nil then |
137 | -- add the mod name as a prefix to match axis icon loading name collision avoidance |
138 | iconName = (self.customEnvironment or "") .. iconName |
139 | end |
140 | |
141 | control.axisActionIcon = iconName |
142 | |
143 | control.invertAxis = self.xmlFile:getValue(key .. "#invertControlAxis", false) |
144 | control.mouseSpeedFactor = self.xmlFile:getValue(key .. "#mouseSpeedFactor", 1.0) |
145 | control.moveAlpha = 0 |
146 | control.moveAlphaSent = 0 |
147 | control.moveAlphaLastManual = 0 |
148 | |
149 | spec.nameToControl[actionBindingName] = control |
150 | table.insert(spec.controls, control) |
151 | |
152 | i = i + 1 |
153 | end |
154 | |
155 | if self.isClient then |
156 | spec.lastMoveTime = 0 |
157 | |
158 | spec.samples = {} |
159 | spec.samples.hydraulic = g_soundManager:loadSampleFromXML(self.xmlFile, baseKey..".sounds", "hydraulic", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
160 | end |
161 | |
162 | spec.jointDesc = nil |
163 | spec.dirtyFlagClient = self:getNextDirtyFlag() -- client values changes, send to server |
164 | spec.dirtyFlagServer = self:getNextDirtyFlag() -- server data changed cause of damping, send to client |
165 | |
166 | if #spec.controls == 0 then |
167 | SpecializationUtil.removeEventListener(self, "onReadStream", AttacherJointControl) |
168 | SpecializationUtil.removeEventListener(self, "onWriteStream", AttacherJointControl) |
169 | SpecializationUtil.removeEventListener(self, "onReadUpdateStream", AttacherJointControl) |
170 | SpecializationUtil.removeEventListener(self, "onWriteUpdateStream", AttacherJointControl) |
171 | SpecializationUtil.removeEventListener(self, "onUpdate", AttacherJointControl) |
172 | SpecializationUtil.removeEventListener(self, "onRegisterActionEvents", AttacherJointControl) |
173 | SpecializationUtil.removeEventListener(self, "onPostAttach", AttacherJointControl) |
174 | SpecializationUtil.removeEventListener(self, "onPreDetach", AttacherJointControl) |
175 | end |
176 | end |
onPostAttach
DescriptionCalled if vehicle gets attachedDefinition
onPostAttach(table attacherVehicle, integer inputJointDescIndex, integer jointDescIndex)Arguments
table | attacherVehicle | attacher vehicle |
integer | inputJointDescIndex | index of input attacher joint |
integer | jointDescIndex | index of attacher joint it gets attached to |
528 | function AttacherJointControl:onPostAttach(attacherVehicle, inputJointDescIndex, jointDescIndex, loadFromSavegame) |
529 | local spec = self.spec_attacherJointControl |
530 | |
531 | local inputAttacherJoints = self:getInputAttacherJoints() |
532 | if inputAttacherJoints[inputJointDescIndex] ~= nil and inputAttacherJoints[inputJointDescIndex].isControllable then |
533 | local attacherJoints = attacherVehicle:getAttacherJoints() |
534 | local jointDesc = attacherJoints[jointDescIndex] |
535 | jointDesc.allowsLoweringBackup = jointDesc.allowsLowering |
536 | jointDesc.allowsLowering = false |
537 | jointDesc.upperRotationOffsetBackup = jointDesc.upperRotationOffset |
538 | jointDesc.lowerRotationOffsetBackup = jointDesc.lowerRotationOffset |
539 | |
540 | spec.jointDesc = jointDesc |
541 | |
542 | -- reset control values |
543 | for _, control in ipairs(spec.controls) do |
544 | control.moveAlpha = control.func(self) |
545 | end |
546 | |
547 | --lift after attach |
548 | if loadFromSavegame then |
549 | if spec.heightController ~= nil then |
550 | self:controlAttacherJoint(spec.heightController, spec.jointDesc.upperAlpha, false) |
551 | end |
552 | else |
553 | spec.heightTargetAlpha = spec.jointDesc.upperAlpha |
554 | end |
555 | |
556 | self:requestActionEventUpdate() |
557 | end |
558 | end |
onPreDetach
DescriptionCalled if vehicle gets detachedDefinition
onPreDetach(table attacherVehicle, table implement)Arguments
table | attacherVehicle | attacher vehicle |
table | implement | implement |
564 | function AttacherJointControl:onPreDetach(attacherVehicle, implement) |
565 | local spec = self.spec_attacherJointControl |
566 | |
567 | if spec.jointDesc ~= nil then |
568 | spec.jointDesc.allowsLowering = spec.jointDesc.allowsLoweringBackup |
569 | spec.jointDesc.upperRotationOffset = spec.jointDesc.upperRotationOffsetBackup |
570 | spec.jointDesc.lowerRotationOffset = spec.jointDesc.lowerRotationOffsetBackup |
571 | spec.jointDesc = nil |
572 | end |
573 | end |
onReadStream
DescriptionCalled on client side on joinDefinition
onReadStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
191 | function AttacherJointControl:onReadStream(streamId, connection) |
192 | if connection:getIsServer() then |
193 | if streamReadBool(streamId) then |
194 | local spec = self.spec_attacherJointControl |
195 | for _, control in ipairs(spec.controls) do |
196 | local moveAlpha = streamReadUIntN(streamId, AttacherJointControl.ALPHA_NUM_BITS) / AttacherJointControl.ALPHA_MAX_VALUE |
197 | self:controlAttacherJoint(control, moveAlpha, false, true) |
198 | end |
199 | end |
200 | end |
201 | end |
onReadUpdateStream
DescriptionCalled on on updateDefinition
onReadUpdateStream(integer streamId, integer timestamp, table connection)Arguments
integer | streamId | stream ID |
integer | timestamp | timestamp |
table | connection | connection |
223 | function AttacherJointControl:onReadUpdateStream(streamId, timestamp, connection) |
224 | local spec = self.spec_attacherJointControl |
225 | if not connection:getIsServer() then |
226 | if streamReadBool(streamId) then |
227 | for _, control in ipairs(spec.controls) do |
228 | local moveAlpha = streamReadUIntN(streamId, AttacherJointControl.ALPHA_NUM_BITS) / AttacherJointControl.ALPHA_MAX_VALUE |
229 | self:controlAttacherJoint(control, moveAlpha, false, true) |
230 | end |
231 | end |
232 | else |
233 | if streamReadBool(streamId) then |
234 | for _, control in ipairs(spec.controls) do |
235 | local moveAlpha = streamReadUIntN(streamId, AttacherJointControl.ALPHA_NUM_BITS) / AttacherJointControl.ALPHA_MAX_VALUE |
236 | self:controlAttacherJoint(control, moveAlpha, false, true) |
237 | end |
238 | end |
239 | end |
240 | end |
onRegisterActionEvents
DescriptionDefinitiononRegisterActionEvents()Code
507 | function AttacherJointControl:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection) |
508 | if self.isClient then |
509 | local spec = self.spec_attacherJointControl |
510 | self:clearActionEventsTable(spec.actionEvents) |
511 | |
512 | if isActiveForInputIgnoreSelection then |
513 | if spec.jointDesc ~= nil then |
514 | for _, control in ipairs(spec.controls) do |
515 | local _, actionEventId = self:addPoweredActionEvent(spec.actionEvents, control.controlAction, self, AttacherJointControl.actionEventAttacherJointControl, false, false, true, true, nil, control.axisActionIcon) |
516 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL) |
517 | end |
518 | end |
519 | end |
520 | end |
521 | 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 |
269 | function AttacherJointControl:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
270 | local spec = self.spec_attacherJointControl |
271 | local control = spec.heightController |
272 | |
273 | --update attacher joint height by target alpha |
274 | if control ~= nil then |
275 | if spec.jointDesc ~= nil then |
276 | if spec.heightTargetAlpha ~= -1 then |
277 | local diff = spec.heightTargetAlpha - control.moveAlpha + 0.0001 |
278 | local moveTime = diff / (spec.jointDesc.upperAlpha - spec.jointDesc.lowerAlpha) * spec.jointDesc.moveTime |
279 | local moveStep = dt / moveTime * diff |
280 | if diff > 0 then |
281 | moveStep = -moveStep |
282 | end |
283 | local newAlpha = control.moveAlpha + moveStep |
284 | self:controlAttacherJoint(control, newAlpha, true, true) |
285 | if math.abs(spec.heightTargetAlpha - newAlpha) < 0.01 then |
286 | spec.heightTargetAlpha = -1 |
287 | end |
288 | end |
289 | |
290 | if self.isServer then |
291 | if spec.supportsDamping then |
292 | -- y axis damping |
293 | if spec.nextHeightDampingUpdateTime < g_time then |
294 | local inputJointDesc = self:getActiveInputAttacherJoint() |
295 | |
296 | local delta = 0 |
297 | if self:getIsAttacherJointControlDampingAllowed() then |
298 | local wX, wY, wZ = getWorldTranslation(inputJointDesc.node) |
299 | local dirX, _, dirZ = localDirectionToWorld(inputJointDesc.node, spec.dampingOffset, 0, 0) |
300 | local posX, posY, posZ = worldToLocal(self.components[1].node, wX+dirX, wY, wZ+dirZ) |
301 | local _, vy, _ = getVelocityAtLocalPos(self.components[1].node, posX, posY, posZ) |
302 | |
303 | --#debug DebugUtil.drawDebugGizmoAtWorldPos(wX+dirX, wY, wZ+dirZ, 0, 1, 0, 1, 0, 0, string.format("vy = %.2f", vy)) |
304 | |
305 | if math.abs(vy) > 0.15 then |
306 | delta = vy * 0.5 |
307 | end |
308 | end |
309 | |
310 | delta = delta + (control.moveAlphaLastManual - control.moveAlpha) * 0.001 * dt |
311 | |
312 | if math.abs(delta) > 0.0001 then |
313 | spec.heightTargetAlpha = MathUtil.clamp(control.moveAlpha + delta, 0, 1) |
314 | if spec.heightTargetAlpha <= 0 then |
315 | if spec.tiltController ~= nil then |
316 | self:controlAttacherJoint(spec.tiltController, MathUtil.clamp(spec.tiltController.moveAlpha - delta * 0.1, 0, 1), true) |
317 | end |
318 | end |
319 | end |
320 | end |
321 | end |
322 | end |
323 | end |
324 | end |
325 | |
326 | if spec.lastMoveTime + 100 > g_time then |
327 | if not g_soundManager:getIsSamplePlaying(spec.samples.hydraulic) then |
328 | g_soundManager:playSample(spec.samples.hydraulic) |
329 | end |
330 | else |
331 | if g_soundManager:getIsSamplePlaying(spec.samples.hydraulic) then |
332 | g_soundManager:stopSample(spec.samples.hydraulic) |
333 | end |
334 | end |
335 | end |
onWriteStream
DescriptionCalled on server side on joinDefinition
onWriteStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
207 | function AttacherJointControl:onWriteStream(streamId, connection) |
208 | if not connection:getIsServer() then |
209 | local spec = self.spec_attacherJointControl |
210 | if streamWriteBool(streamId, spec.jointDesc ~= nil) then |
211 | for _, control in ipairs(spec.controls) do |
212 | streamWriteUIntN(streamId, control.moveAlpha * AttacherJointControl.ALPHA_MAX_VALUE, AttacherJointControl.ALPHA_NUM_BITS) |
213 | end |
214 | end |
215 | end |
216 | end |
onWriteUpdateStream
DescriptionCalled on on updateDefinition
onWriteUpdateStream(integer streamId, table connection, integer dirtyMask)Arguments
integer | streamId | stream ID |
table | connection | connection |
integer | dirtyMask | dirty mask |
247 | function AttacherJointControl:onWriteUpdateStream(streamId, connection, dirtyMask) |
248 | local spec = self.spec_attacherJointControl |
249 | if connection:getIsServer() then |
250 | if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlagClient) ~= 0) then |
251 | for _, control in ipairs(spec.controls) do |
252 | streamWriteUIntN(streamId, control.moveAlpha * AttacherJointControl.ALPHA_MAX_VALUE, AttacherJointControl.ALPHA_NUM_BITS) |
253 | end |
254 | end |
255 | else |
256 | if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlagServer) ~= 0) then |
257 | for _, control in ipairs(spec.controls) do |
258 | streamWriteUIntN(streamId, control.moveAlpha * AttacherJointControl.ALPHA_MAX_VALUE, AttacherJointControl.ALPHA_NUM_BITS) |
259 | end |
260 | end |
261 | end |
262 | 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 |
20 | function AttacherJointControl.prerequisitesPresent(specializations) |
21 | return SpecializationUtil.hasSpecialization(Attachable, specializations) |
22 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
68 | function AttacherJointControl.registerEventListeners(vehicleType) |
69 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", AttacherJointControl) |
70 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", AttacherJointControl) |
71 | SpecializationUtil.registerEventListener(vehicleType, "onReadStream", AttacherJointControl) |
72 | SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", AttacherJointControl) |
73 | SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", AttacherJointControl) |
74 | SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", AttacherJointControl) |
75 | SpecializationUtil.registerEventListener(vehicleType, "onUpdate", AttacherJointControl) |
76 | SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", AttacherJointControl) |
77 | SpecializationUtil.registerEventListener(vehicleType, "onPostAttach", AttacherJointControl) |
78 | SpecializationUtil.registerEventListener(vehicleType, "onPreDetach", AttacherJointControl) |
79 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
49 | function AttacherJointControl.registerFunctions(vehicleType) |
50 | SpecializationUtil.registerFunction(vehicleType, "controlAttacherJoint", AttacherJointControl.controlAttacherJoint) |
51 | SpecializationUtil.registerFunction(vehicleType, "controlAttacherJointHeight", AttacherJointControl.controlAttacherJointHeight) |
52 | SpecializationUtil.registerFunction(vehicleType, "controlAttacherJointTilt", AttacherJointControl.controlAttacherJointTilt) |
53 | SpecializationUtil.registerFunction(vehicleType, "getControlAttacherJointDirection", AttacherJointControl.getControlAttacherJointDirection) |
54 | SpecializationUtil.registerFunction(vehicleType, "getIsAttacherJointControlDampingAllowed", AttacherJointControl.getIsAttacherJointControlDampingAllowed) |
55 | end |
registerLoweringActionEvent
DescriptionDefinitionregisterLoweringActionEvent()Code
463 | function AttacherJointControl:registerLoweringActionEvent(superFunc, actionEventsTable, inputAction, target, callback, triggerUp, triggerDown, triggerAlways, startActive, callbackState, customIconName) |
464 | local spec = self.spec_attacherJointControl |
465 | if spec.heightController then |
466 | local _, actionEventId = self:addPoweredActionEvent(actionEventsTable, InputAction.LOWER_IMPLEMENT, self, AttacherJointControl.actionEventAttacherJointControlSetPoint, triggerUp, triggerDown, triggerAlways, startActive, callbackState, customIconName) |
467 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_HIGH) |
468 | |
469 | if inputAction == InputAction.LOWER_IMPLEMENT then |
470 | return |
471 | end |
472 | end |
473 | |
474 | superFunc(self, actionEventsTable, inputAction, target, callback, triggerUp, triggerDown, triggerAlways, startActive, callbackState, customIconName) |
475 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
59 | function AttacherJointControl.registerOverwrittenFunctions(vehicleType) |
60 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadInputAttacherJoint", AttacherJointControl.loadInputAttacherJoint) |
61 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "registerLoweringActionEvent", AttacherJointControl.registerLoweringActionEvent) |
62 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getLoweringActionEventState", AttacherJointControl.getLoweringActionEventState) |
63 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", AttacherJointControl.getCanBeSelected) |
64 | end |