Action denied

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 pairs(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  
  54                  elseif v.transAxis ~= nil then
  55                      mp.transAxis    = v.transAxis or 1;
  56                      mp.transMin     = v.transMin or 0;
  57                      mp.transMax     = v.transMax or 0;
  58                  end;
  59  
  60                  mp.moveSpeed        = 0.001 * (v.moveSpeed or 20);
  61                  mp.position         = v.position or 0.5;
  62  
  63                  if v.inputAxis ~= nil then
  64                      mp.inputAxis    = InputMapper[v.inputAxis];
  65                      mp.axisSpeed    = v.axisSpeed;
  66                      table.insert(self.movingPartsByInputAxis, mp);
  67                  end;
  68  
  69                  table.insert(self.movingParts, mp);
  70  
  71                  self:setMovingPartPosition(#self.movingParts, mp.position);
  72              end;
  73          end;
  74      end;
  75  end;

MovingParts:saveToTable(tbl)

Stores the position of each moving part in the savegame.

  79  function MovingParts:saveToTable(tbl)
  80      if tbl == nil then return end;
  81  
  82      tbl.movingParts                 = {};
  83  
  84      for k, mp in pairs(self.movingParts) do
  85          tbl.movingParts[k]          = mp.position;
  86      end;
  87  end;

MovingParts:loadFromTable(tbl)

Restores moving part positions.

  91  function MovingParts:loadFromTable(tbl)
  92      if tbl == nil then return end;
  93      if tbl.movingParts == nil then return end;
  94  
  95      for k, mp in pairs(self.movingParts) do
  96          local position              = tbl.movingParts[k];
  97          if position ~= nil then
  98              self:setMovingPartPosition(k, position);
  99          end;
 100      end;
 101  end;

MovingParts:setMovingPartPosition(key, pos)

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.

 105  function MovingParts:setMovingPartPosition(key, pos)
 106      local mp                        = self.movingParts[key or 0];
 107  
 108      if mp == nil then return end;
 109  
 110      mp.position                     = clamp01(pos or 0);
 111  
 112      if mp.rotAxis ~= nil then
 113          local rotValue              = lerp(mp.rotMin, mp.rotMax, mp.position);
 114          
 115          if mp.rotAxis == 1 then
 116              setRotationX(mp.id, rotValue);
 117          elseif mp.rotAxis == 2 then
 118              setRotationY(mp.id, rotValue);
 119          else
 120              setRotationZ(mp.id, rotValue);
 121          end;
 122      end;
 123      if mp.transAxis ~= nil then
 124          local transValue            = lerp(mp.transMin, mp.transMax, mp.position);
 125  
 126          if mp.transAxis == 1 then
 127              setPositionX(mp.id, transValue);
 128          elseif mp.transAxis == 2 then
 129              setPositionY(mp.id, transValue);
 130          else
 131              setPositionZ(mp.id, transValue);
 132          end;
 133      end;
 134  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.

 138  function MovingParts:update(dt)
 139      if not self.isActive then return end;
 140  
 141      -- move the blade by input axis
 142      for key, mp in pairs(self.movingPartsByInputAxis) do
 143          local inputValue            = InputMapper:getAxis(mp.inputAxis) * (mp.axisSpeed or 1);
 144  
 145          if inputValue ~= 0 then
 146              self:setMovingPartPosition(key, mp.position + inputValue * GameplaySettings.joystickSensitivity * dt);
 147          end;
 148      end;
 149  
 150      -- input is active - let's update our moving parts
 151      local lmb                       = Input.getMouseButton(0);
 152      local rmb                       = Input.getMouseButton(1);
 153      local activeMouseButton         = (lmb and rmb and 3) or (lmb and 1) or (rmb and 2) or 0;
 154  
 155      if activeMouseButton == 0 and self.movingPartsButtonDown ~= 0 then
 156          self.movingPartsButtonDown  = 0;
 157  
 158          if VehicleCamera.activeCamera ~= nil then
 159              VehicleCamera.activeCamera:setBlockInput(false);
 160          end;
 161          return;
 162      end;
 163      self.movingPartsButtonDown      = self.movingPartsButtonDown + dt;
 164  
 165      -- freeze camera after 200 ms
 166      if self.movingPartsButtonDown > 0.2 and VehicleCamera.activeCamera ~= nil then
 167          VehicleCamera.activeCamera:setBlockInput(true);
 168      end;
 169  
 170      -- there's a mouse button active
 171      for key, mp in pairs(self.movingParts) do
 172          if activeMouseButton == mp.mouseButton then
 173              -- this one is moving
 174              local mouseMovement     = 0;
 175              if mp.mouseAxis == 1 then
 176                  mouseMovement       = Input.getAxis("Mouse X");
 177              else
 178                  mouseMovement       = Input.getAxis("Mouse Y");
 179              end;
 180  
 181              self:setMovingPartPosition(key, mp.position + mouseMovement * mp.moveSpeed);
 182          end;
 183      end;
 184  end;

All contents of this page may be used for modding use for Winter Resort Simulator only. Any use exceeding this regulation is not permitted.

Copyright (C) HR Innoways, 2020. All Rights Reserved.