meta data for this page
Vehicles/VehicleScripts/Seats.lua
Seats is the script which makes the vehicle enterable, i.e. without this script, you cannot enter the vehicle at all (neither via the Tab
key nor by clicking some control element). The most common use-case of non-enterable vehicles are snow cannons. For most other vehicles (such as car, snowcats, snow mobiles, tractors, …) it makes sense to have this vehicle script active.
Generally, every time you can take place on a seat, this seat will be powered by VehicleSeat. This is true for vehicles and ropeway carriers, but also for stationary objects (e.g. sun deck chairs or the chairs in some ropeway control rooms).
Note: Seats supports multiple seats (that can be used either as second driver seat or as passenger seat). This means you can have multiple seats in your vehicle from which it can be controlled.
29 Seats = Seats or {}; 30 Seats.playerNameColor = { 200, 10, 10 };
Seats:load(dataTable, isCarrier)
Load the configuration data (i.e. what seats are there and what cameras can be enabled).
Currently, the camera slot
can be between 1 and 4 (1 = interior camera, 2 = exterior camera, 3 and 4 = custom cameras)
Note that this function is also used to initialize the seats of ropeway carriers. In that case, self
represents the ropeway carrier instance (instead of the vehicle instance). dataTable
will be the carrier's data table.
37 function Seats:load(dataTable, isCarrier) 38 self.seats = {}; 39 self.driverSeat = nil; -- main driver seat (for tab function) 40 self.nonTabbable = self.nonTabbable or false; -- could be overridden by other vehicleScripts 41 42 -- isCarrier must be false for vehicles 43 isCarrier = isCarrier or false; 44 45 local cameras = {}; 46 self.camerasToDestroy = {}; 47 48 -- note that the data table MUST consist cameras if you want to have working seats. 49 for n, v in pairs(dataTable.cameras) do 50 local camIndex = v.index or ""; 51 local rotIndex = v.rotIndex or ""; 52 local zoomIndex = v.zoomIndex or ""; 53 local isInterieur = v.isInterieur or false; 54 local maxCameraAccelerationZoom = v.maxCameraAccelerationZoom or 0; 55 local camId = getChild(self.id, camIndex); 56 local rotId, zoomId = nil, nil; 57 58 if rotIndex ~= "" then rotId = getChild(self.id, rotIndex); end; 59 if zoomIndex ~= "" then zoomId = getChild(self.id, zoomIndex); end; 60 61 -- create a new camera and make sure its destroy is correctly called upon destroying the vehicle 62 local camera = VehicleCamera:new(camId, rotId, zoomId, isCarrier, self.id, maxCameraAccelerationZoom); 63 table.insert(self.camerasToDestroy, camera); 64 65 cameras[n] = camera; 66 cameras[n].slot = v.slot or 2; 67 cameras[n].isInterieur = isInterieur; 68 end; 69 70 for i, v in pairs(dataTable.seats) do 71 local seatIndex = v.index or ""; 72 73 if seatIndex == "" then break else 74 75 local colId = getChild(self.id, seatIndex); 76 local camId = getChild(self.id, v.cameraIndex or ""); 77 local leaveId = getChild(self.id, v.leaveIndex or ""); 78 local characterNode = nil; 79 if v.characterIndex ~= nil then 80 characterNode = getChild(self.id, v.characterIndex); 81 end; 82 83 local characterPose = v.characterPose or "VehicleSit"; 84 local footIk = nil; 85 if v.footIk ~= nil then 86 footIk = { 87 footIkLeft = getChild(self.id, v.footIk.footIkLeft), 88 footIkRight = getChild(self.id, v.footIk.footIkRight), 89 }; 90 end; 91 local handIk = nil; 92 if v.handIk ~= nil then 93 handIk = { 94 handIkLeft = getChild(self.id, v.handIk.handIkLeft), 95 handIkRight = getChild(self.id, v.handIk.handIkRight), 96 }; 97 end; 98 99 local seat = VehicleSeat:new(colId, camId, leaveId, characterNode, characterPose, footIk, handIk, isCarrier); 100 if not isCarrier and v.isDriver and self.driverSeat == nil then 101 -- only one driver seat allowed (because of multiplayer) 102 seat:setParentVehicle(self, true); 103 self.driverSeat = seat; 104 else 105 seat:setParentVehicle(self, false); 106 end; 107 108 self:registerNewSeat(seat); 109 110 table.insert(self.seats, seat); 111 112 for n, camera in pairs(cameras) do 113 local slotId = camera.slot; 114 seat:addCamera(slotId, camera); 115 end; 116 end; 117 end; 118 119 self.isInterieurCamera = true; 120 self.currentCharacter = nil; 121 if not isCarrier then 122 if dataTable.playerNameLabel ~= nil then 123 self.playerNameLabel = getChild(self.id, dataTable.playerNameLabel); 124 else 125 -- automatically create it 126 self.playerNameLabel = createGameObject("PlayerNameLabel"); 127 setParent(self.playerNameLabel, self.mainId); 128 setPosition(self.playerNameLabel, 0, 2.5, 0); 129 end; 130 end; 131 132 end;
Seats:saveToTable(tbl, isCarrier)
Contrary to some other games, we always save the currently active camera position. If the player saves the game while sitting in a vehicle, that vehicle will also be active after loading the savegame, and even the same camera will be active.
136 function Seats:saveToTable(tbl, isCarrier) 137 if tbl == nil then return end; 138 139 -- save all seats, but save cameras only once 140 tbl.seats = {}; 141 local withoutCameras = false; 142 143 for k, v in pairs(self.seats) do 144 -- note: for carriers, we only save the one seat where the player is actually sitting 145 if not isCarrier or v.seatActive then 146 tbl.seats[k] = v:saveToTable(nil, withoutCameras); 147 withoutCameras = true; 148 end; 149 end; 150 end;
Seats:loadFromTable(tbl)
Pass the data from our savegame on to the VehicleSeat.
154 function Seats:loadFromTable(tbl) 155 if tbl == nil then return end; 156 if tbl.seats == nil then return end; 157 158 for k, v in pairs(self.seats) do 159 local seatTbl = tbl.seats[k]; 160 161 if seatTbl ~= nil then 162 v:loadFromTable(seatTbl); 163 end; 164 end; 165 end;
Seats:update(dt)
Not in use any more
169 function Seats:update(dt) 170 -- don't update seats (this is done by BaseScenario)! 171 end;
Seats:destroy()
173 function Seats:destroy() 174 for _, seat in pairs(self.seats) do 175 seat:destroy(); 176 end; 177 178 for k, v in pairs(self.camerasToDestroy) do 179 v:destroy(); 180 end; 181 end;
Seats:onEnter(player, isLocalPlayer)
Place the player character on the seat if a player enters the vehicle.
185 function Seats:onEnter(player, isLocalPlayer) 186 -- connect sitting character to seats script 187 self.currentCharacter = player.playerCharacterSit; 188 189 self.driverSeat.currentPlayerCharacter = self.currentCharacter; 190 191 if self.driverSeat.characterNode ~= nil then 192 -- enable player 193 setActive(self.currentCharacter, true); 194 195 -- set parent and bind player to seat 196 setParent(self.currentCharacter, self.driverSeat.characterNode); 197 setPosition(self.currentCharacter, 0,0,0); 198 setRotation(self.currentCharacter, 0,0,0); 199 200 if self.driverSeat.footIk ~= nil then 201 self.currentUser.footIkTargetLeft = self.driverSeat.footIk.footIkLeft; 202 self.currentUser.footIkTargetRight = self.driverSeat.footIk.footIkRight; 203 else 204 self.currentUser.footIkTargetLeft = nil; 205 self.currentUser.footIkTargetRight = nil; 206 end; 207 end; 208 209 setActive(self.currentCharacter, not isLocalPlayer or not self.driverSeat.isInterieurCamera); 210 211 -- set player IK hand targets 212 self.currentUser.handIkTargetLeft = self.anchorSteeringLeftIK; 213 self.currentUser.handIkTargetRight = self.anchorSteeringRightIK; 214 215 if isLocalPlayer and self.driverSeat ~= nil then 216 self.driverSeat:onEnter(player, isLocalPlayer); 217 end; 218 219 -- apply sit animation 220 if self.driverSeat.characterPose ~= nil then 221 Animator.setTrigger(self.currentCharacter, self.driverSeat.characterPose); 222 end; 223 end; 224 --[[ 225 Remove the player character from the seat when the player leaves the vehicle. 226 function Seats:onLeave(player, isLocalPlayer) 227 player.handIkTargetLeft = nil; 228 player.handIkTargetRight = nil; 229 230 -- check for character nodes 231 if self.driverSeat.characterNode ~= nil then 232 -- set the parent of the character to 0 and apply position 233 setParent(self.currentCharacter, 0); 234 setPosition(self.currentCharacter, 0,0,0); 235 end; 236 237 if isLocalPlayer and self.driverSeat ~= nil and self.driverSeat.seatActive then 238 self.driverSeat:onLeave(player, isLocalPlayer); 239 end; 240 end;
Seats:onGUI()
Render nicknames in multiplayer.
245 function Seats:onGUI() 246 if g_isMultiplayer and not GameplaySettings.hideMultiplayerNicknames then 247 if self.playerNameLabel and self.currentUser ~= nil and self.currentUser ~= g_scenario.player and self.currentUser.playerName ~= nil and not g_GUI:getAnyGuiActive() then 248 local wx,wy,wz = getWorldPosition(self.playerNameLabel); 249 local x,y,z = Camera.worldToScreenPoint(wx,wy,wz); 250 local sqrDist = GameControl.getCameraSqrDistance(wx,wy,wz); 251 252 -- only render nicknames of players closer than 100m 253 if z > 0 and sqrDist < 100*100 then 254 local width, height = Screen.getSize(); 255 256 IMGUI.setAlignment("MiddleCenter"); 257 IMGUI.setColor(self.currentUser:unpackHexColor()); 258 259 -- adjust font size depending on distance 260 local fontSize = mapClamped(0, 100*100, 18, 10, sqrDist); 261 local labelWidth, labelHeight = 400, 2*fontSize; 262 local px, py = x - labelWidth*0.5, height-y - labelHeight * 0.5; 263 264 if px > 0 and py > 0 and px < width and py < height then 265 IMGUI.setFontSize(fontSize); 266 IMGUI.renderLabel(px, py, labelWidth, labelHeight, self.currentUser.playerName); 267 end; 268 end; 269 end; 270 end; 271 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.