meta data for this page
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 self.setCustomLightState = VehicleManager:newFunction("setCustomLightState"); 38 self.setRotatableLightRotation = VehicleManager:newFunction("setRotatableLightRotation"); 39 40 if dataTable.lights ~= nil then 41 self.headlightIds = VehicleLighting.loadLights(self, dataTable.lights.headlights); 42 self.brakelightIds = VehicleLighting.loadLights(self, dataTable.lights.brakelights); 43 self.reverselightIds = VehicleLighting.loadLights(self, dataTable.lights.reverselights); 44 self.turnLeftLightIds = VehicleLighting.loadLights(self, dataTable.lights.leftIndicator); 45 self.turnRightLightIds = VehicleLighting.loadLights(self, dataTable.lights.rightIndicator); 46 self.beaconLightIds = VehicleLighting.loadLights(self, dataTable.lights.beaconLights); 47 self.strobeLightIds = VehicleLighting.loadLights(self, dataTable.lights.strobeLights); 48 49 -- inverse of them 50 self.headlightIds0 = VehicleLighting.loadLights(self, dataTable.lights.headlightsInverse); 51 self.brakelightIds0 = VehicleLighting.loadLights(self, dataTable.lights.brakelightsInverse); 52 self.reverselightIds0 = VehicleLighting.loadLights(self, dataTable.lights.reverselightsInverse); 53 self.turnLeftLightIds0 = VehicleLighting.loadLights(self, dataTable.lights.leftIndicatorInverse); 54 self.turnRightLightIds0 = VehicleLighting.loadLights(self, dataTable.lights.rightIndicatorInverse); 55 self.beaconLightIds0 = VehicleLighting.loadLights(self, dataTable.lights.beaconLightsInverse); 56 self.strobeLightIds0 = VehicleLighting.loadLights(self, dataTable.lights.strobeLightsInverse); 57 58 -- low/high beam 59 self.lowBeamIds = VehicleLighting.loadLights(self, dataTable.lights.lowBeam); 60 self.lowBeamIds0 = VehicleLighting.loadLights(self, dataTable.lights.lowBeamInverse); 61 self.highBeamIds = VehicleLighting.loadLights(self, dataTable.lights.highBeam); 62 self.highBeamIds0 = VehicleLighting.loadLights(self, dataTable.lights.highBeamInverse); 63 64 if dataTable.lights.customLights ~= nil then 65 self.customLights = {}; 66 self.customLightsByOrder= {}; 67 68 for k, v in pairs(dataTable.lights.customLights) do 69 local light = { 70 ids = VehicleLighting.loadLights(self, v.indexes), 71 inverseIds = VehicleLighting.loadLights(self, v.indexesInverse), 72 inputKey = v.inputKey or "", 73 state = v.state or false, 74 name = v.name or k, 75 key = #self.customLightsByOrder + 1, 76 }; 77 self.customLights[light.name] = light; 78 table.insert(self.customLightsByOrder, light); 79 80 VehicleLighting.setLightsState(self, light.ids, light.inverseIds, light.state); 81 end; 82 end; 83 if dataTable.lights.rotatableLights ~= nil then 84 self.rotatableLights = {}; 85 for k,light in ipairs(dataTable.lights.rotatableLights) do 86 local rotLight = { 87 controlId = getChild(self.id, light.controlId), 88 light = getChild(self.id, light.rotatableLight), 89 rotation = 0; 90 } 91 92 if rotLight.controlId ~= nil then 93 ControlElement.new(rotLight.controlId); 94 95 ControlElement.setCallback(rotLight.controlId, 2, 96 function() 97 rotLight.rotation = rotLight.rotation + Input.getAxis("Mouse X") * 2; 98 self:setRotatableLightRotation(k, rotLight.rotation); 99 end 100 ); 101 102 ControlElement.setName(rotLight.controlId, l10n.get("controlElement_searchLightRotation")); 103 end; 104 105 table.insert(self.rotatableLights, rotLight); 106 end; 107 end; 108 end; 109 110 self.headlightsState = 0; -- 0: off, 1: low beam, 2: high beam 111 self.turnLightsState = 0; -- 0: off, 1: left, 2: right, 3: both 112 self.beaconLightOn = false; 113 114 self.beaconLightsRotSpeed = dataTable.lights ~= nil and dataTable.lights.beaconLightsRotSpeed or 200; -- degrees per second 115 self.strobeLightsPace = dataTable.lights ~= nil and dataTable.lights.strobeLightsPace or 1; 116 117 self.blinkPulse = false; 118 self.lastBlinkPulse = false; 119 120 if dataTable.sounds ~= nil then 121 self.blinkTickOn = self:loadSingleSound(dataTable.sounds.blinkTickOn); 122 self.blinkTickOff = self:loadSingleSound(dataTable.sounds.blinkTickOff); 123 end; 124 125 self:setTurnLightsState(0, true); 126 self:setHeadlightsState(0, true); 127 self:setBeaconLightsState(false, true); 128 end;
VehicleLighting:saveToTable(tbl)
Saves the current state of all lights to the savegame.
132 function VehicleLighting:saveToTable(tbl) 133 if tbl == nil then return end; 134 135 tbl.headlightsState = self.headlightsState; 136 tbl.beaconLightOn = self.beaconLightOn; 137 138 -- save turn lights state 139 tbl.turnLightsState = self.turnLightsState; 140 141 if self.customLights ~= nil then 142 tbl.customLights = {}; 143 144 for k, v in pairs(self.customLights) do 145 tbl.customLights[k] = v.state; 146 end; 147 end; 148 end;
VehicleLighting:loadFromTable(tbl)
Applies the state of all lights in the savegame.
152 function VehicleLighting:loadFromTable(tbl) 153 if tbl == nil then return end; 154 155 self:setHeadlightsState(tbl.headlightsState or 0); 156 self:setTurnLightsState(tbl.turnLightsState or 0); 157 self:setBeaconLightsState(tbl.beaconLightOn or false); 158 159 if self.customLights ~= nil and tbl.customLights ~= nil then 160 for k, v in pairs(self.customLights) do 161 if tbl.customLights[k] ~= nil then 162 self:setCustomLightState(v.key, tbl.customLights[k]); 163 end; 164 end; 165 end; 166 end;
VehicleLighting:loadLights(dataTable)
This helper function actually loads the light's indices. It is only called by the code in VehicleLighting:load()
.
170 function VehicleLighting:loadLights(dataTable) 171 if dataTable == nil then 172 return nil; 173 end; 174 local ids = {}; 175 176 for i, v in pairs(dataTable) do 177 local headlightsIndex = v or ""; 178 179 if headlightsIndex == "" then break else 180 table.insert(ids, getChild(self.id, headlightsIndex)); 181 end; 182 183 i = i + 1; 184 end; 185 return ids; 186 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.
192 function VehicleLighting:setLightsState(lights, inverseLights, state) 193 if lights ~= nil then 194 for _, id in pairs(lights) do 195 setActive(id, state or false); 196 end; 197 end; 198 if inverseLights ~= nil then 199 for _, id in pairs(inverseLights) do 200 setActive(id, not state); 201 end; 202 end; 203 end;
VehicleLighting:setHeadlightsState(state, noEvent)
Turns the headlights on/off, depending on state
(int, range 0-2: 0 = off, 1 = low beam, 2 = high beam).
207 function VehicleLighting:setHeadlightsState(state, noEvent) 208 if state > 2 or (state > 1 and self.highBeamIds == nil) then 209 state = 0; 210 end; 211 self.headlightsState = state; 212 213 VehicleLighting.setLightsState(self, self.headlightIds, self.headlightIds0, state > 0); 214 VehicleLighting.setLightsState(self, self.lowBeamIds, self.lowBeamIds0, state == 1); 215 VehicleLighting.setLightsState(self, self.highBeamIds, self.highBeamIds0, state == 2); 216 217 if not noEvent then 218 EventSetLightState:send(self, self.headlightsState, self.turnLightsState, self.beaconLightOn); 219 end; 220 end;
VehicleLighting:setBeaconLightsState(state, noEvent)
Turns the beacon/strobe lights on or off, depending on state
(bool).
224 function VehicleLighting:setBeaconLightsState(state, noEvent) 225 self.beaconLightOn = state; 226 227 VehicleLighting.setLightsState(self, self.beaconLightIds, self.beaconLightIds0, state); 228 229 if not state then 230 VehicleLighting.setLightsState(self, self.strobeLightIds, self.strobeLightIds0, false); 231 end; 232 233 if not noEvent then 234 EventSetLightState:send(self, self.headlightsState, self.turnLightsState, self.beaconLightOn); 235 end; 236 end;
VehicleLighting:setCustomLightState(key, state, noEvent)
Turns the custom light named key
(string) on or off, depending on state
(bool).
240 function VehicleLighting:setCustomLightState(key, state, noEvent) 241 local customLight = self.customLightsByOrder[key or 1]; 242 243 if customLight == nil then return end; 244 245 customLight.state = state; 246 247 VehicleLighting.setLightsState(self, customLight.ids, customLight.inverseIds, state); 248 249 if not noEvent then 250 EventSetCustomLight:send(self, key, state); 251 end; 252 end;
VehicleLighting:setTurnLightsState(state, noEvent)
Sets the turn lights on or off, depending on state
(0 = off, 1 = turn left, 2 = turn right, 3 = hazard lights)
256 function VehicleLighting:setTurnLightsState(state, noEvent) 257 self.turnLightsLeftActive = state == 1 or state == 3; 258 self.turnLightsRightActive = state == 2 or state == 3; 259 260 self.turnLightsState = state; 261 262 if not noEvent then 263 EventSetLightState:send(self, self.headlightsState, self.turnLightsState, self.beaconLightOn); 264 end; 265 end;
VehicleLighting:setRotatableLightRotation(key, rotY, noEvent)
Sets the rotation of lights, that can be rotated over control elements.
269 function VehicleLighting:setRotatableLightRotation(key, rotY, noEvent) 270 self.rotatableLights[key].rotation = rotY; 271 setRotationY(self.rotatableLights[key].light, rotY); 272 273 if not noEvent then 274 EventSetLightRotation:send(self, key, rotY); 275 end; 276 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.
279 function VehicleLighting:update(dt) 280 if self:getIsInputActive() then 281 if g_scenario.environment.isNight ~= (self.headlightsState ~= 0) then 282 g_GUI:addKeyHint(InputMapper.Vehicle_Lights, l10n.get("Input_Vehicle_Lights")); 283 end; 284 285 if InputMapper:getKeyDown(InputMapper.Vehicle_Lights) then 286 self:setHeadlightsState(self.headlightsState + 1); 287 self:playOnOffSound(self.headlightsState > 0, self.switchSound1, self.switchSound0); 288 end; 289 290 if InputMapper:getKeyDown(InputMapper.VehicleCar_IndicatorLeft) then 291 self:setTurnLightsState(self.turnLightsLeftActive and 0 or 1); 292 self:playOnOffSound(self.turnLightsLeftActive, self.switchSound1, self.switchSound0); 293 end; 294 if InputMapper:getKeyDown(InputMapper.VehicleCar_HazardLights) then 295 self:setTurnLightsState((self.turnLightsLeftActive and self.turnLightsRightActive) and 0 or 3); 296 self:playOnOffSound(self.turnLightsLeftActive, self.switchSound1, self.switchSound0); 297 end; 298 if InputMapper:getKeyDown(InputMapper.VehicleCar_IndicatorRight) then 299 self:setTurnLightsState(self.turnLightsRightActive and 0 or 2); 300 self:playOnOffSound(self.turnLightsRightActive, self.switchSound1, self.switchSound0); 301 end; 302 if InputMapper:getKeyDown(InputMapper.Vehicle_BeaconLight) then 303 self:setBeaconLightsState(not self.beaconLightOn); 304 self:playOnOffSound(self.beaconLightOn, self.switchSound1, self.switchSound0); 305 end; 306 307 if self.customLights ~= nil then 308 for k, v in pairs(self.customLights) do 309 if v.inputKey ~= "" and InputMapper:getKeyDown(InputMapper[v.inputKey]) then 310 self:setCustomLightState(v.key, not v.state); 311 self:playOnOffSound(v.state, self.switchSound1, self.switchSound0); 312 end; 313 end; 314 end; 315 end; 316 317 -- set brake lights state 318 VehicleLighting.setLightsState(self, self.brakelightIds, self.brakelightIds0, self.brakeValue > 1e-4); 319 VehicleLighting.setLightsState(self, self.reverselightIds, self.reverselightIds0, self.currentGear == 1); 320 321 -- set turn lights state 322 self.lastBlinkPulse = self.blinkPulse; 323 self.blinkPulse = (getTime() % 1) < 0.5; 324 VehicleLighting.setLightsState(self, self.turnLeftLightIds, self.turnLeftLightIds0, self.turnLightsLeftActive and self.blinkPulse); 325 VehicleLighting.setLightsState(self, self.turnRightLightIds, self.turnRightLightIds0, self.turnLightsRightActive and self.blinkPulse); 326 327 if self.beaconLightOn then 328 -- update beacon lights 329 if self.beaconLightIds ~= nil then 330 for _, id in pairs(self.beaconLightIds) do 331 rotate(id, 0, self.beaconLightsRotSpeed * dt, 0, false); 332 end; 333 end; 334 335 -- and strobe lights 336 if self.strobeLightsPace ~= nil then 337 local strobeLightsTime = (getTime() % self.strobeLightsPace) / self.strobeLightsPace; 338 local strobeState = (strobeLightsTime < 0.12) or (strobeLightsTime > 0.3 and strobeLightsTime < 0.42); 339 340 VehicleLighting.setLightsState(self, self.strobeLightIds, self.strobeLightIds0, strobeState); 341 end; 342 end; 343 344 if self:getIsGUIActive() then 345 if self.turnLightsLeftActive or self.turnLightsRightActive then 346 347 if self.lastBlinkPulse ~= self.blinkPulse then 348 self:playOnOffSound(self.blinkPulse, self.blinkTickOn, self.blinkTickOff); 349 end; 350 end; 351 352 self.vehicleHUD:setTurnLights(self.turnLightsLeftActive and self.blinkPulse, self.turnLightsRightActive and self.blinkPulse); 353 self.vehicleHUD:setLights(self.headlightsState == 1, self.headlightsState == 2); 354 end; 355 end;
VehicleLighting:onLeave(player, isLocalPlayer)
Stops the indicator sound if the player has left the vehicle.
359 function VehicleLighting:onLeave(player, isLocalPlayer) 360 -- stop playing audio 361 if isLocalPlayer then 362 if self.blinkTickOn ~= nil then AudioSource.stop(self.blinkTickOn); end; 363 if self.blinkTickOff ~= nil then AudioSource.stop(self.blinkTickOff); end; 364 end; 365 end;
VehicleLighting:writeResync()
Resynchronizes all variables when a new player joins the game. The data sent by writeResync
will be received by readResync
.
369 function VehicleLighting:writeResync() 370 streamBeginWriteBitwise(); 371 streamWriteUIntN(self.headlightsState, 2); 372 streamWriteUIntN(self.turnLightsState, 2); 373 streamWriteBit(self.beaconLightOn); 374 375 if self.customLightsByOrder ~= nil then 376 for k, v in ipairs(self.customLightsByOrder) do 377 streamWriteBit(v.state); 378 end; 379 end; 380 381 streamEndWriteBitwise(); 382 end;
VehicleLighting:readResync()
Resynchronizes all variables when a new player joins the game. The data sent by writeResync
will be received by readResync
.
386 function VehicleLighting:readResync() 387 streamBeginReadBitwise(); 388 local headlight = streamReadUIntN(2); 389 local turnLight = streamReadUIntN(2); 390 local beaconLight = streamReadBit(); 391 392 if self.customLightsByOrder ~= nil then 393 for k, v in ipairs(self.customLightsByOrder) do 394 self:setCustomLightState(v.key, streamReadBit(), true); 395 end; 396 end; 397 398 streamEndReadBitwise(); 399 400 self:setHeadlightsState(headlight, true); 401 self:setTurnLightsState(turnLight, true); 402 self:setBeaconLightsState(beaconLight, true); 403 end;
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.