meta data for this page
Vehicles/VehicleScripts/MovingParts.lua
MovingParts implements an option to have some translation or rotation parts that can be moved using an Input axis (either by key, by mouse or by joystick). The script is used for smooth movement of the snowcat's snow blade. You may find the script useful for any axis that should be fine-controllable.
Contrary to AnimatedParts, moving parts do not have to be in one of two fixed positions (open/closed or similar) but rather anywhere between those positions.
27 28 MovingParts = MovingParts or {};
MovingParts:load(dataTable)
Load the configuration data for each moving part axis.
32 function MovingParts:load(dataTable) 33 self.setMovingPartPosition = VehicleManager:newFunction("setMovingPartPosition"); 34 35 self.movingParts = {}; 36 self.movingPartsByInputAxis = {}; 37 self.movingPartsButtonDown = 0; 38 39 if dataTable.movingParts ~= nil then 40 for k, v in ipairs(dataTable.movingParts) do 41 local id = getChild(self.id, v.index or ""); 42 43 if id ~= 0 then 44 local mp = {}; 45 mp.id = id; 46 mp.mouseButton = v.mouseButton or 0; 47 mp.mouseAxis = v.mouseAxis or 0; 48 49 if v.rotAxis ~= nil then 50 mp.rotAxis = v.rotAxis or 1; 51 mp.rotMin = v.rotMin or 0; 52 mp.rotMax = v.rotMax or 0; 53 if v.noRotChild ~= nil then 54 mp.noRotChild = getChild(self.id, v.noRotChild); 55 end; 56 57 elseif v.transAxis ~= nil then 58 mp.transAxis = v.transAxis or 1; 59 mp.transMin = v.transMin or 0; 60 mp.transMax = v.transMax or 0; 61 end; 62 63 mp.moveSpeed = 0.001 * (v.moveSpeed or 20); 64 mp.position = v.position or 0.5; 65 66 if v.inputAxis ~= nil then 67 mp.inputAxis = InputMapper[v.inputAxis]; 68 mp.axisSpeed = v.axisSpeed; 69 table.insert(self.movingPartsByInputAxis, mp); 70 end; 71 72 table.insert(self.movingParts, mp); 73 74 self:setMovingPartPosition(#self.movingParts, mp.position, true); 75 end; 76 end; 77 end; 78 end;
MovingParts:saveToTable(tbl)
Stores the position of each moving part in the savegame.
82 function MovingParts:saveToTable(tbl) 83 if tbl == nil then return end; 84 85 tbl.movingParts = {}; 86 87 for k, mp in pairs(self.movingParts) do 88 tbl.movingParts[k] = mp.position; 89 end; 90 end;
MovingParts:loadFromTable(tbl)
Restores moving part positions.
94 function MovingParts:loadFromTable(tbl) 95 if tbl == nil then return end; 96 if tbl.movingParts == nil then return end; 97 98 for k, mp in pairs(self.movingParts) do 99 local position = tbl.movingParts[k]; 100 if position ~= nil then 101 self:setMovingPartPosition(k, position); 102 end; 103 end; 104 end;
MovingParts:setMovingPartPosition(key, pos, noEvent)
Sets the position of the moving part number key
(int, starting with 1) to pos
(float, range 0 to 1), and directly applies it to the object.noEvent
(bool) specifies whether the multiplayer event shall be suppressed.
The corresponding network event is EventSetMovingPartPosition.
110 function MovingParts:setMovingPartPosition(key, pos, noEvent) 111 local mp = self.movingParts[key or 0]; 112 113 if mp == nil then return end; 114 115 mp.position = clamp01(pos or 0); 116 117 if mp.rotAxis ~= nil then 118 local rotValue = lerp(mp.rotMin, mp.rotMax, mp.position); 119 120 if mp.rotAxis == 1 then 121 setRotationX(mp.id, rotValue); 122 123 if mp.noRotChild ~= nil then 124 setRotationX(mp.noRotChild, -rotValue); 125 end; 126 elseif mp.rotAxis == 2 then 127 setRotationY(mp.id, rotValue); 128 129 if mp.noRotChild ~= nil then 130 setRotationY(mp.noRotChild, -rotValue); 131 end; 132 else 133 setRotationZ(mp.id, rotValue); 134 135 if mp.noRotChild ~= nil then 136 setRotationY(mp.noRotChild, -rotValue); 137 end; 138 end; 139 end; 140 if mp.transAxis ~= nil then 141 local transValue = lerp(mp.transMin, mp.transMax, mp.position); 142 143 if mp.transAxis == 1 then 144 setPositionX(mp.id, transValue); 145 elseif mp.transAxis == 2 then 146 setPositionY(mp.id, transValue); 147 else 148 setPositionZ(mp.id, transValue); 149 end; 150 end; 151 152 if not noEvent then 153 EventSetMovingPartPosition:send(self, key, mp.position); 154 end; 155 end;
MovingParts:update(dt)
Update player input. First check each axis' inputAxis (to allow for joystick control), afterwards check whether the player wants to move it using the mouse.
159 function MovingParts:update(dt) 160 if not self:getIsInputActive() then 161 return; 162 end; 163 164 -- move the blade by input axis 165 for key, mp in pairs(self.movingPartsByInputAxis) do 166 local inputValue = InputMapper:getAxis(mp.inputAxis) * (mp.axisSpeed or 1); 167 168 if inputValue ~= 0 then 169 self:setMovingPartPosition(key, mp.position + inputValue * GameplaySettings.joystickSensitivity * dt); 170 end; 171 end; 172 173 -- input is active - let's update our moving parts 174 local lmb = Input.getMouseButton(0); 175 local rmb = Input.getMouseButton(1); 176 local activeMouseButton = (lmb and rmb and 3) or (lmb and 1) or (rmb and 2) or 0; 177 178 if activeMouseButton == 0 and self.movingPartsButtonDown ~= 0 then 179 self.movingPartsButtonDown = 0; 180 181 if VehicleCamera.activeCamera ~= nil then 182 VehicleCamera.activeCamera:setBlockInput(false); 183 end; 184 return; 185 end; 186 self.movingPartsButtonDown = self.movingPartsButtonDown + dt; 187 188 -- freeze camera after 200 ms 189 if self.movingPartsButtonDown > 0.2 and VehicleCamera.activeCamera ~= nil then 190 VehicleCamera.activeCamera:setBlockInput(true); 191 end; 192 193 -- there's a mouse button active 194 for key, mp in pairs(self.movingParts) do 195 if activeMouseButton == mp.mouseButton then 196 -- this one is moving 197 local mouseMovement = 0; 198 if mp.mouseAxis == 1 then 199 mouseMovement = Input.getAxis("Mouse X"); 200 else 201 mouseMovement = Input.getAxis("Mouse Y"); 202 end; 203 204 self:setMovingPartPosition(key, mp.position + mouseMovement * mp.moveSpeed); 205 end; 206 end; 207 end;
MovingParts:writeResync()
Resynchronizes all variables when a new player joins the game. The data sent by writeResync
will be received by readResync
.
211 function MovingParts:writeResync() 212 for k, mp in ipairs(self.movingParts) do 213 streamWriteFloat(mp.position); 214 end; 215 end;
MovingParts:readResync()
Resynchronizes all variables when a new player joins the game. The data sent by writeResync
will be received by readResync
.
218 function MovingParts:readResync() 219 for k, mp in ipairs(self.movingParts) do 220 self:setMovingPartPosition(k, streamReadFloat(), true); 221 end; 222 end; 223
Copyright
All contents of this page may be used for modding use for Winter Resort Simulator - Season 2 only. Any use exceeding this regulation is not permitted.
Copyright (C) HR Innoways, 2021. All Rights Reserved.