Vehicles/VehicleScripts/VehicleLighting.lua

VehicleLighting implements various different types of lights (headlights, low/high beam, brake lights, reverse lights, turn lights, beacon lights, strobe lights and custom lights).

  25  VehicleLighting                     = VehicleLighting or {};

VehicleLighting:load(dataTable)

This function sets up all necessary functions and afterwards loads the configuration for each individual light type.

Note that any inverse lights will always be turned on if the actual light is off (e.g. lights in headlightsInverse will be only off if the ones in headlights are turned on). This can be helpful if you have Z-fighting issues, where multiple objects are rendered at the same position.

  31  function VehicleLighting:load(dataTable)
  32      -- let's get to load our stuff
  33      self.setHeadlightsState         = VehicleManager:newFunction("setHeadlightsState");
  34      self.setTurnLightsState         = VehicleManager:newFunction("setTurnLightsState");
  35      self.setBeaconLightsState       = VehicleManager:newFunction("setBeaconLightsState");
  36      self.setCustomLightState        = VehicleManager:newFunction("setCustomLightState");
  37      
  38      if dataTable.lights ~= nil then
  39          self.headlightIds           = VehicleLighting.loadLights(self, dataTable.lights.headlights);
  40          self.brakelightIds          = VehicleLighting.loadLights(self, dataTable.lights.brakelights);
  41          self.reverselightIds        = VehicleLighting.loadLights(self, dataTable.lights.reverselights);
  42          self.turnLeftLightIds       = VehicleLighting.loadLights(self, dataTable.lights.leftIndicator);
  43          self.turnRightLightIds      = VehicleLighting.loadLights(self, dataTable.lights.rightIndicator);
  44          self.beaconLightIds         = VehicleLighting.loadLights(self, dataTable.lights.beaconLights);
  45          self.strobeLightIds         = VehicleLighting.loadLights(self, dataTable.lights.strobeLights);
  46  
  47          -- inverse of them
  48          self.headlightIds0          = VehicleLighting.loadLights(self, dataTable.lights.headlightsInverse);
  49          self.brakelightIds0         = VehicleLighting.loadLights(self, dataTable.lights.brakelightsInverse);
  50          self.reverselightIds0       = VehicleLighting.loadLights(self, dataTable.lights.reverselightsInverse);
  51          self.turnLeftLightIds0      = VehicleLighting.loadLights(self, dataTable.lights.leftIndicatorInverse);
  52          self.turnRightLightIds0     = VehicleLighting.loadLights(self, dataTable.lights.rightIndicatorInverse);
  53          self.beaconLightIds0        = VehicleLighting.loadLights(self, dataTable.lights.beaconLightsInverse);
  54          self.strobeLightIds0        = VehicleLighting.loadLights(self, dataTable.lights.strobeLightsInverse);
  55          
  56          -- low/high beam
  57          self.lowBeamIds             = VehicleLighting.loadLights(self, dataTable.lights.lowBeam);
  58          self.lowBeamIds0            = VehicleLighting.loadLights(self, dataTable.lights.lowBeamInverse);
  59          self.highBeamIds            = VehicleLighting.loadLights(self, dataTable.lights.highBeam);
  60          self.highBeamIds0           = VehicleLighting.loadLights(self, dataTable.lights.highBeamInverse);
  61  
  62          if dataTable.lights.customLights ~= nil then
  63              self.customLights       = {};
  64              for k, v in pairs(dataTable.lights.customLights) do
  65                  local light         = {
  66                      ids             = VehicleLighting.loadLights(self, v.indexes),
  67                      inverseIds      = VehicleLighting.loadLights(self, v.indexesInverse),
  68                      inputKey        = v.inputKey or "",
  69                      state           = v.state or false,
  70                      name            = v.name or k,
  71                  };
  72                  self.customLights[light.name]   = light;
  73  
  74                  VehicleLighting.setLightsState(self, light.ids, light.inverseIds, light.state);
  75              end;
  76          end;
  77      end;
  78  
  79      self.headlightsState            = 0; -- 0: off, 1: low beam, 2: high beam
  80      self.beaconLightOn              = false;
  81  
  82      self.beaconLightsRotSpeed       = dataTable.lights ~= nil and dataTable.lights.beaconLightsRotSpeed or 200; -- degrees per second
  83      self.strobeLightsPace           = dataTable.lights ~= nil and dataTable.lights.strobeLightsPace     or 1;
  84      
  85      self.blinkPulse                 = false;
  86      self.lastBlinkPulse             = false;
  87  
  88      if dataTable.sounds ~= nil then
  89          self.blinkTickOn            = self:loadSingleSound(dataTable.sounds.blinkTickOn);
  90          self.blinkTickOff           = self:loadSingleSound(dataTable.sounds.blinkTickOff);
  91      end;
  92  
  93      self:setTurnLightsState(0);
  94      self:setHeadlightsState(0);
  95      self:setBeaconLightsState(false);
  96  end;

VehicleLighting:saveToTable(tbl)

Saves the current state of all lights to the savegame.

 100  function VehicleLighting:saveToTable(tbl)
 101      if tbl == nil then return end;
 102  
 103      tbl.headlightsState             = self.headlightsState;
 104      tbl.beaconLightOn               = self.beaconLightOn;
 105  
 106      -- save turn lights state
 107      if self.turnLightsLeftActive and self.turnLightsRightActive then
 108          tbl.turnLightsState             = 3;
 109          
 110      elseif self.turnLightsLeftActive then
 111          tbl.turnLightsState             = 1;
 112  
 113      elseif self.turnLightsRightActive then
 114          tbl.turnLightsState             = 2;
 115  
 116      else
 117          tbl.turnLightsState             = 0;
 118      end;
 119  
 120      if self.customLights ~= nil then
 121          tbl.customLights                = {};
 122  
 123          for k, v in pairs(self.customLights) do
 124              tbl.customLights[k]         = v.state;
 125          end;
 126      end;
 127  end;

VehicleLighting:loadFromTable(tbl)

Applies the state of all lights in the savegame.

 131  function VehicleLighting:loadFromTable(tbl)
 132      if tbl == nil then return end;
 133  
 134      self:setHeadlightsState(tbl.headlightsState or 0);
 135      self:setTurnLightsState(tbl.turnLightsState or 0);
 136      self:setBeaconLightsState(tbl.beaconLightOn or false);
 137  
 138      if self.customLights ~= nil and tbl.customLights ~= nil then
 139          for k, v in pairs(self.customLights) do
 140              if tbl.customLights[k] ~= nil then
 141                  self:setCustomLightState(k, tbl.customLights[k]);
 142              end;
 143          end;
 144      end;
 145  end;

VehicleLighting:loadLights(dataTable)

This helper function actually loads the light's indices. It is only called by the code in VehicleLighting:load().

 149  function VehicleLighting:loadLights(dataTable)
 150      if dataTable == nil then
 151          return nil;
 152      end;
 153      local ids                       = {};
 154      
 155      for i, v in pairs(dataTable) do
 156          local headlightsIndex       = v or "";
 157          
 158          if headlightsIndex == "" then break else
 159              table.insert(ids, getChild(self.id, headlightsIndex));
 160          end;
 161          
 162          i                           = i + 1;
 163      end;
 164      return ids;
 165  end;

VehicleLighting:setLightsState(lights, inverseLights, state)

This is a helper function again, which helps us make our code easier and shorter. All objects within lights will be set to active/inactive depending on state (bool). All objects within inverseLights will be set to the exact inverse state.

 171  function VehicleLighting:setLightsState(lights, inverseLights, state)
 172      if lights ~= nil then
 173          for _, id in pairs(lights) do
 174              setActive(id, state or false);
 175          end;
 176      end;
 177      if inverseLights ~= nil then
 178          for _, id in pairs(inverseLights) do
 179              setActive(id, not state);
 180          end;
 181      end;
 182  end;

VehicleLighting:setHeadlightsState(state)

Turns the headlights on/off, depending on state (int, range 0-2: 0 = off, 1 = low beam, 2 = high beam).

 186  function VehicleLighting:setHeadlightsState(state)
 187      if state > 2 or (state > 1 and self.highBeamIds == nil) then
 188          state                       = 0;
 189      end;
 190      self.headlightsState            = state;
 191  
 192      VehicleLighting.setLightsState(self, self.headlightIds, self.headlightIds0, state > 0);
 193      VehicleLighting.setLightsState(self, self.lowBeamIds,   self.lowBeamIds0,   state == 1);
 194      VehicleLighting.setLightsState(self, self.highBeamIds,  self.highBeamIds0,  state == 2);
 195  end;

VehicleLighting:setBeaconLightsState(state)

Turns the beacon/strobe lights on or off, depending on state (bool).

 199  function VehicleLighting:setBeaconLightsState(state)
 200      self.beaconLightOn              = state;
 201      
 202      VehicleLighting.setLightsState(self, self.beaconLightIds, self.beaconLightIds0, state);
 203  
 204      if not state then
 205          VehicleLighting.setLightsState(self, self.strobeLightIds, self.strobeLightIds0, false);
 206      end;
 207  end;

VehicleLighting:setCustomLightState(key, state)

Turns the custom light named key (string) on or off, depending on state (bool).

 211  function VehicleLighting:setCustomLightState(key, state)
 212      local customLight               = self.customLights[key or ""];
 213  
 214      if customLight == nil then return end;
 215  
 216      customLight.state               = state;
 217  
 218      VehicleLighting.setLightsState(self, customLight.ids, customLight.inverseIds, state);
 219  end;

VehicleLighting:setTurnLightsState(state)

Sets the turn lights on or off, depending on state (0 = off, 1 = turn left, 2 = turn right, 3 = hazard lights)

 223  function VehicleLighting:setTurnLightsState(state)
 224      self.turnLightsLeftActive       = state == 1 or state == 3;
 225      self.turnLightsRightActive      = state == 2 or state == 3;
 226  end;

VehicleLighting:update(dt)

Checks whether the player wants to switch any lights on or off. Some lights (such as indicators or beacon lights) need to be updated every frame.

 229  function VehicleLighting:update(dt)
 230      if self:getIsInputActive() then
 231          if g_scenario.environment.isNight ~= (self.headlightsState ~= 0) then
 232              g_GUI:addKeyHint(InputMapper.Vehicle_Lights,    l10n.get("Input_Vehicle_Lights"));
 233          end;
 234          
 235          if InputMapper:getKeyDown(InputMapper.Vehicle_Lights) then
 236              self:setHeadlightsState(self.headlightsState + 1);
 237              self:playOnOffSound(self.headlightsState > 0, self.switchSound1, self.switchSound0);
 238          end;
 239          
 240          if InputMapper:getKeyDown(InputMapper.VehicleCar_IndicatorLeft) then
 241              self:setTurnLightsState(self.turnLightsLeftActive and 0 or 1);
 242              self:playOnOffSound(self.turnLightsLeftActive, self.switchSound1, self.switchSound0);
 243          end;
 244          if InputMapper:getKeyDown(InputMapper.VehicleCar_HazardLights) then
 245              self:setTurnLightsState((self.turnLightsLeftActive and self.turnLightsRightActive) and 0 or 3);
 246              self:playOnOffSound(self.turnLightsLeftActive, self.switchSound1, self.switchSound0);
 247          end;
 248          if InputMapper:getKeyDown(InputMapper.VehicleCar_IndicatorRight) then
 249              self:setTurnLightsState(self.turnLightsRightActive and 0 or 2);
 250              self:playOnOffSound(self.turnLightsRightActive, self.switchSound1, self.switchSound0);
 251          end;
 252          if InputMapper:getKeyDown(InputMapper.Vehicle_BeaconLight) then
 253              self:setBeaconLightsState(not self.beaconLightOn);
 254              self:playOnOffSound(self.beaconLightOn, self.switchSound1, self.switchSound0);
 255          end;
 256  
 257          if self.customLights ~= nil then
 258              for k, v in pairs(self.customLights) do
 259                  if v.inputKey ~= "" and InputMapper:getKeyDown(InputMapper[v.inputKey]) then
 260                      self:setCustomLightState(k, not v.state);
 261                      self:playOnOffSound(v.state, self.switchSound1, self.switchSound0);
 262                  end;
 263              end;
 264          end;
 265      end;
 266      
 267      -- set brake lights state
 268      VehicleLighting.setLightsState(self, self.brakelightIds,    self.brakelightIds0,    self.brakeValue > 1e-4);
 269      VehicleLighting.setLightsState(self, self.reverselightIds,  self.reverselightIds0,  self.getGearTransmissionRatio ~= nil and self:getGearTransmissionRatio() < -1e-4);
 270      
 271      -- set turn lights state
 272      self.lastBlinkPulse             = self.blinkPulse;
 273      self.blinkPulse                 = (getTime() % 1) < 0.5;
 274      VehicleLighting.setLightsState(self, self.turnLeftLightIds,     self.turnLeftLightIds0,     self.turnLightsLeftActive  and self.blinkPulse);
 275      VehicleLighting.setLightsState(self, self.turnRightLightIds,    self.turnRightLightIds0,    self.turnLightsRightActive and self.blinkPulse);
 276  
 277      if self.beaconLightOn then
 278          -- update beacon lights
 279          if self.beaconLightIds ~= nil then
 280              for _, id in pairs(self.beaconLightIds) do
 281                  rotate(id, 0, self.beaconLightsRotSpeed * dt, 0, false);
 282              end;
 283          end;
 284  
 285          -- and strobe lights
 286          if self.strobeLightsPace ~= nil then
 287              local strobeLightsTime  = (getTime() % self.strobeLightsPace) / self.strobeLightsPace;
 288              local strobeState       = (strobeLightsTime < 0.12) or (strobeLightsTime > 0.3 and strobeLightsTime < 0.42);
 289  
 290              VehicleLighting.setLightsState(self, self.strobeLightIds, self.strobeLightIds0, strobeState);
 291          end;
 292      end;
 293      
 294      if self.isEntered then
 295          if self.turnLightsLeftActive or self.turnLightsRightActive then
 296  
 297              if self.lastBlinkPulse ~= self.blinkPulse then
 298                  self:playOnOffSound(self.blinkPulse, self.blinkTickOn, self.blinkTickOff);
 299              end;
 300          end;
 301          setActive(getChild(GUI.vehicleHUD, "Icons1/IndicatorLeft/dark"),                not (self.turnLightsLeftActive  and self.blinkPulse));
 302          setActive(getChild(GUI.vehicleHUD, "Icons1/IndicatorLeft/bright"),              self.turnLightsLeftActive       and self.blinkPulse);
 303          setActive(getChild(GUI.vehicleHUD, "Icons1/IndicatorRight/dark"),               not (self.turnLightsRightActive and self.blinkPulse));
 304          setActive(getChild(GUI.vehicleHUD, "Icons1/IndicatorRight/bright"),             self.turnLightsRightActive      and self.blinkPulse);
 305          
 306          setActive(getChild(GUI.vehicleHUD, "Icons2/LowBeam/dark"),                      self.headlightsState ~= 1);
 307          setActive(getChild(GUI.vehicleHUD, "Icons2/LowBeam/bright"),                    self.headlightsState == 1);
 308          setActive(getChild(GUI.vehicleHUD, "Icons2/HighBeam/dark"),                     self.headlightsState ~= 2);
 309          setActive(getChild(GUI.vehicleHUD, "Icons2/HighBeam/bright"),                   self.headlightsState == 2);
 310      end;
 311  end;

VehicleLighting:onLeave()

Stops the indicator sound if the player has left the vehicle.

 315  function VehicleLighting:onLeave()
 316      -- stop playing audio
 317      if self.blinkTickOn ~= nil then         AudioSource.stop(self.blinkTickOn);         end;
 318      if self.blinkTickOff ~= nil then        AudioSource.stop(self.blinkTickOff);        end;
 319  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.