meta data for this page
Vehicles/VehicleSeat.lua
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).
Regarding the implementation in vehicles, have a look at the Seats vehicle script. Some functions of it are also in use for ropeway carriers.
26 g_currentVehicleSeat = g_currentVehicleSeat or nil; 27 28 VehicleSeat = VehicleSeat or {}; 29 local VehicleSeatClass = Class(VehicleSeat); 30 31 VehicleSeat.staticSeatKeysBySeat = VehicleSeat.staticSeatKeysBySeat or {}; 32 VehicleSeat.staticSeatsByKey = VehicleSeat.staticSeatsByKey or {}; 33
VehicleSeat.controlElementActive()
Returns whether the seat's control element shall be active. Only active control elements can be clicked.
37 function VehicleSeat.controlElementActive() 38 return (g_scenario.player ~= nil and g_scenario.player:getIsLocalPlayerEntered()) and g_currentVehicleSeat == nil; 39 end; 40
VehicleSeat.leaveActiveSeat(isEnteringOtherVehicle)
This will make the player leave any active seat.
44 function VehicleSeat.leaveActiveSeat(isEnteringOtherVehicle) 45 if g_currentVehicleSeat == nil then return end; 46 47 -- leave that seat 48 g_currentVehicleSeat:localLeaveRequest(isEnteringOtherVehicle); 49 end; 50
VehicleSeat.registerStaticSeat(seat, savegameKey)
Function to register static seats.
53 function VehicleSeat.registerStaticSeat(seat, savegameKey) 54 VehicleSeat.staticSeatKeysBySeat[seat] = savegameKey; 55 VehicleSeat.staticSeatsByKey[savegameKey] = seat; 56 57 seat:assignSeatId(savegameKey); 58 end; 59
VehicleSeat.unregisterStaticSeat(seat)
Function to unregister static keys.
62 function VehicleSeat.unregisterStaticSeat(seat) 63 local key = VehicleSeat.staticSeatKeysBySeat[seat]; 64 65 if key == nil then 66 return false; 67 end; 68 69 VehicleSeat.staticSeatsByKey[key] = nil; 70 VehicleSeat.staticSeatKeysBySeat[seat] = nil; 71 return true; 72 end; 73
VehicleSeat.getStaticSeatByKey(key)
Returns a static seat with the given key (if existing, otherwise nil).
76 function VehicleSeat.getStaticSeatByKey(key) 77 return VehicleSeat.staticSeatsByKey[key]; 78 end; 79
VehicleSeat:onCreateStaticSeat(id, cameraId, leaveNode, ...)
This function can be called for static objects (such as the chair in a command room) using following arguments:
id
(int): id of the seat's control element.cameraId
(int): id of the transform which the camera shall be placed at.leaveNode
(int): id of the transform where the player will be placed at upon leaving the seat.
86 function VehicleSeat:onCreateStaticSeat(id, cameraId, leaveNode, ...) 87 cameraId = cameraId or getChildAt(id, 0); 88 leaveNode = leaveNode or getChildAt(id, 1); 89 90 -- create a new seat which handles all updateable stuff itself 91 local seat = VehicleSeat:new(id, cameraId, leaveNode, ...); 92 seat.savegameKey = string.format("seat:%s @ (%.4f, %.4f, %.4f)", getName(id), getWorldPosition(id)); 93 seat.isStaticSeat = true; 94 95 -- assign the savegame key as id to the seat 96 VehicleSeat.registerStaticSeat(seat, seat.savegameKey); 97 98 g_scenario:addObjectAndLoad(seat, id); 99 return seat; 100 end; 101
VehicleSeat:load(id, cameraId, leaveNode, characterNode, characterPose, footIk, handIk, ...)
Loads a newly created instance using the following parameters:
id
(int): id of the seat's control element.cameraId
(int): id of the transform which the camera shall be placed at.leaveNode
(int): id of the transform where the player will be placed at upon leaving the seat.…
: Arguments passed on to VehicleCamera.
109 function VehicleSeat:load(id, cameraId, leaveNode, characterNode, characterPose, footIk, handIk, ...) 110 self.id = id; 111 112 ControlElement.new(self.id); 113 ControlElement.setCallback(self.id, 1, self, "localEnterRequest"); 114 ControlElement.setActiveCallback(self.id, VehicleSeat.controlElementActive); 115 ControlElement.setName(self.id, l10n.get("EnterSeat")); 116 117 local firstCamera = VehicleCamera:new(cameraId, nil,nil, ...); 118 firstCamera.isInterieur = true; 119 120 self.mainCamera = firstCamera; 121 self.cameraSlots = {}; 122 self.cameraSlots[1] = { firstCamera }; 123 self.activeCamera = self.cameraSlots[1][1]; 124 125 self.camerasToDestroy = { firstCamera }; 126 127 self.selectedSlot = 1; 128 self.selectedIndex = 1; 129 130 self.seatActive = false; 131 self.leaveNode = leaveNode; 132 self.characterNode = characterNode; 133 self.characterPose = characterPose; 134 self.footIk = footIk; 135 self.handIk = handIk; 136 self.enteredOnSkis = false; 137 self.isInterieurCamera = true; 138 139 self.currentPlayerCharacter = nil; 140 end; 141 142 --[[ 143 Assigns the given parameters as seat id for multiplayer synchronisation. Internal use only. 144 function VehicleSeat:assignSeatId(...) 145 self.seatId = { ... }; 146 end; 147 148 --[[ 149 Assigns the parent vehicle as required for multiplayer synchronisation. Internal use only. 150 function VehicleSeat:setParentVehicle(vehicle, isDriverSeat) 151 self.vehicle = vehicle; 152 self.isDriverSeat = isDriverSeat; 153 end; 154
VehicleSeat:saveToTable(parentTable, withoutCameras)
Saves all relevant variables to the savegames.
159 function VehicleSeat:saveToTable(parentTable, withoutCameras) 160 local tbl = { 161 seatActive = self.seatActive, 162 selectedSlot = self.selectedSlot, 163 selectedIndex = self.selectedIndex, 164 enteredOnSkis = self.enteredOnSkis, 165 }; 166 -- safety layer 167 local ignoreCamera = false; 168 if self.cameraSlots ~= nil then 169 for slotNo, slot in pairs(self.cameraSlots) do 170 for cameraNo, v in pairs(slot) do 171 if not ignoreCamera then 172 tbl["camera" .. slotNo .. "_" .. cameraNo] = v:saveToTable(); 173 end; 174 ignoreCamera = withoutCameras; 175 end; 176 end; 177 end; 178 179 if self.savegameKey ~= nil and parentTable ~= nil then 180 -- static instance 181 parentTable[self.savegameKey] = tbl; 182 else 183 return tbl; 184 end; 185 end; 186
VehicleSeat:loadFromTable(tbl)
Restore all relevant variables from the savegame, and if necessary, enter the seat.
190 function VehicleSeat:loadFromTable(tbl) 191 if tbl == nil then return end; 192 193 if self.savegameKey ~= nil then 194 tbl = tbl[self.savegameKey]; 195 196 if tbl == nil then return end; 197 end; 198 199 self.seatActive = getNoNil(tbl.seatActive, self.seatActive); 200 201 if self.seatActive then 202 self:localEnterRequest(); 203 end; 204 205 self.selectedSlot = getNoNil(tbl.selectedSlot, self.selectedSlot); 206 self.selectedIndex = getNoNil(tbl.selectedIndex, self.selectedIndex); 207 self.enteredOnSkis = getNoNil(tbl.enteredOnSkis, self.enteredOnSkis); 208 209 if self.cameraSlots ~= nil then 210 for slotNo, slot in pairs(self.cameraSlots) do 211 for cameraNo, v in pairs(slot) do 212 local cameraTbl = tbl["camera" .. slotNo .. "_" .. cameraNo]; 213 214 if cameraTbl ~= nil then 215 v:loadFromTable(cameraTbl); 216 217 if cameraTbl.isActive then 218 self.activeCamera = v; 219 end; 220 end; 221 end; 222 end; 223 end; 224 225 -- refresh active camera 226 if self.seatActive then 227 self:selectCamera(self.activeCamera); 228 self:onEnter(g_scenario.player, g_scenario.player.isLocalPlayer); 229 end; 230 end;
VehicleSeat:destroy()
232 function VehicleSeat:destroy() 233 ControlElement.destroy(self.id); 234 235 for k, v in pairs(self.camerasToDestroy) do 236 v:destroy(); 237 end; 238 239 if self.isStaticSeat then 240 VehicleSeat.unregisterStaticSeat(self); 241 242 if g_scenario ~= nil then 243 g_scenario:removeObject(self); 244 end; 245 end; 246 end;
VehicleSeat:addCamera(slotNo, camera)
Adds the VehicleCamera camera
to the slot number slotNo
(int, range 1-4).
250 function VehicleSeat:addCamera(slotNo, camera) 251 local slot = self.cameraSlots[slotNo]; 252 if slot == nil then 253 slot = {}; 254 self.cameraSlots[slotNo] = slot; 255 end; 256 257 table.insert(slot, camera); 258 end;
VehicleSeat:getMayEnter(player)
Returns whether the player player
may enter this seat.
261 function VehicleSeat:getMayEnter(player) 262 -- vehicle must have a driver seat and noone else can sit in there 263 return (self.currentUser == nil or self.currentUser == player); 264 end;
VehicleSeat:getIsLocalPlayerEntered()
Returns whether the local player (of your local game instance) is entered in this seat.
267 function VehicleSeat:getIsLocalPlayerEntered() 268 return self.currentUser == g_scenario.player; 269 end;
VehicleSeat:getMinimapPositionAndRotation()
Returns the current position and rotation of the vehicle seat on the minimap (called by MinimapHUD).
272 function VehicleSeat:getMinimapPositionAndRotation() 273 local referenceId = self.cameraSlots[1][1].cameraId; 274 275 -- sanity check to make sure this seat has not been deleted 276 if not getIsTransformValid(referenceId) then 277 return 0,0,0,0; 278 end; 279 280 local x,y,z = getWorldPosition(referenceId); 281 local _a, ry, _b = getWorldRotation(referenceId); 282 return x,y,z, ry; 283 end;
VehicleSeat:localEnterRequest()
Is called if the player clicks the seat's control element.
288 function VehicleSeat:localEnterRequest() 289 -- if we are in multiplayer, this will be handled by the server! 290 if g_isClient then 291 EventRequestEnterVehicleSeat:send(unpack(self.seatId)); 292 else 293 self:enterRequest(g_scenario.player); 294 end; 295 end;
VehicleSeat:enterRequest(player)
Is called whenever a player
(table, reference to the PlayerController) is trying to enter the seat.
299 function VehicleSeat:enterRequest(player) 300 assert(g_isMaster, "Not allowed on MP clients"); 301 302 if self.vehicle ~= nil and self.isDriverSeat then 303 -- different story for driver seats 304 self.vehicle:handleEnterRequest(player); 305 else 306 self:setCurrentUser(player); 307 end; 308 end;
VehicleSeat:localLeaveRequest(isEnteringOtherVehicle)
Is called when the local player (of your local game instance) wants to leave the seat.
312 function VehicleSeat:localLeaveRequest(isEnteringOtherVehicle) 313 if g_isClient then 314 EventRequestLeaveVehicleSeat:send(isEnteringOtherVehicle or false, unpack(self.seatId)); 315 else 316 self:leaveRequest(g_scenario.player, isEnteringOtherVehicle); 317 end; 318 end;
VehicleSeat:leaveRequest(player, isEnteringOtherVehicle)
Leave request on servers (as triggered by the event sent in localLeaveRequest()
)
322 function VehicleSeat:leaveRequest(player, isEnteringOtherVehicle) 323 assert(g_isMaster, "Not allowed on MP clients"); 324 assert(player, "Must be called with a valid player on it"); 325 326 if self.vehicle ~= nil and self.isDriverSeat then 327 self.vehicle:handleLeave(player); 328 else 329 if not isEnteringOtherVehicle then 330 player:setCurrentUser(player); 331 end; 332 end; 333 end; 334
VehicleSeat:setCurrentUser(newPlayer, noEvent)
Implements some features for seats that are similar to network entities, actually also utilising a part of the network entities.
338 function VehicleSeat:setCurrentUser(newPlayer, noEvent) 339 assert(not self.isDriverSeat, "Not allowed for driver seats"); 340 local oldPlayer = self.currentUser; 341 342 if oldPlayer == nil and newPlayer == nil then 343 return; 344 end; 345 346 347 if oldPlayer ~= nil and newPlayer ~= nil then 348 if oldPlayer == newPlayer then 349 -- same player => don't do anything 350 return; 351 end; 352 353 -- first kick out the old player if this is on a client 354 -- on a server its not allowed though 355 if g_isClient then 356 self:setCurrentUser(nil, true); 357 358 else 359 self:setCurrentUser(nil); 360 error("currentUser must be nil before assigning a new user on a server"); 361 end; 362 end; 363 364 if g_isClient and self.currentUser == newPlayer then 365 -- we already have the correct state (i.e. when leaving the vehicle) 366 return; 367 end; 368 369 -- note: this code block is from NetworkEntity:setCurrentUser! 370 NetworkEntity.setCurrentUser(self, newPlayer, noEvent, EventSetVehicleSeatUser, self.seatId); 371 372 if oldPlayer ~= nil then 373 -- !!TODO!! correct? 374 self:onLeave(oldPlayer, oldPlayer:getIsLocalPlayer()); 375 oldPlayer:quitUsingEntity(self); 376 end; 377 378 if newPlayer ~= nil then 379 newPlayer:startUsingEntity(self); 380 self:onEnter(newPlayer, newPlayer:getIsLocalPlayer()); 381 end; 382 end;
VehicleSeat:resyncCurrentUser()
Resynchronizes the current user of this seat to all clients.
386 function VehicleSeat:resyncCurrentUser() 387 assert(g_isServer, "Only allowed on server"); 388 389 NetworkEntity.resyncCurrentUser(self, EventSetVehicleSeatUser, self.seatId); 390 end; 391
VehicleSeat:onEnter(player, isLocalPlayer)
Is called when player
enters this vehicle seat. Do not call this to let the player enter the seat!
395 function VehicleSeat:onEnter(player, isLocalPlayer) 396 self.currentUser = player; 397 398 -- enable player 399 if self.currentUser.playerCharacterSit ~= nil then 400 setActive(self.currentUser.playerCharacterSit, not (self.isInterieurCamera and isLocalPlayer)); 401 end; 402 403 if self.characterNode ~= nil and self.characterNode ~= "" then 404 -- set parent and bind player to seat 405 setParent(self.currentUser.playerCharacterSit, self.characterNode); 406 setPosition(self.currentUser.playerCharacterSit, 0,0,0); 407 setRotation(self.currentUser.playerCharacterSit, 0,0,0); 408 409 if self.footIk ~= nil then 410 self.currentUser.footIkTargetLeft = self.footIk.footIkLeft; 411 self.currentUser.footIkTargetRight = self.footIk.footIkRight; 412 else 413 self.currentUser.footIkTargetLeft = nil; 414 self.currentUser.footIkTargetRight = nil; 415 end; 416 417 if not self.isDriverSeat then 418 if self.handIk ~= nil then 419 self.currentUser.handIkTargetLeft = self.handIk.handIkLeft; 420 self.currentUser.handIkTargetRight = self.handIk.handIkRight; 421 else 422 -- set player IK hand targetss 423 self.currentUser.handIkTargetLeft = self.currentUser.passengerHandIkTargetLeft; 424 self.currentUser.handIkTargetRight = self.currentUser.passengerHandIkTargetRight; 425 end; 426 end; 427 428 else 429 setActive(self.currentUser.playerCharacterSit, false); 430 end; 431 432 self.currentUser.playerSpatialBlend = 0; 433 434 if not isLocalPlayer then 435 return; 436 end; 437 438 if g_currentVehicleSeat ~= nil then 439 --g_currentVehicleSeat:onLeave(); 440 return; 441 end; 442 443 g_currentVehicleSeat = self; 444 445 self.seatActive = true; 446 self.enteredOnSkis = false;--g_scenario.player.skierController.isActive; 447 448 self.activeCamera:activate(); 449 end; 450
VehicleSeat:onLeave(player, isLocalPlayer)
Is called when the player leave this particular seat. Do not call this to let the player leave the seat!
453 function VehicleSeat:onLeave(player, isLocalPlayer) 454 setActive(player.playerCharacterSit, false); 455 456 -- set parent and bind player to seat 457 setParent(player.playerCharacterSit, 0); 458 setPosition(player.playerCharacterSit, 0,0,0); 459 setRotation(player.playerCharacterSit, 0,0,0); 460 461 player.footIkTargetLeft = nil; 462 player.footIkTargetRight = nil; 463 464 player.playerSpatialBlend = 1; 465 466 self.currentUser = nil; 467 468 469 if not isLocalPlayer then 470 return; 471 end; 472 473 self.seatActive = false; 474 475 if g_currentVehicleSeat ~= self then 476 return; 477 end; 478 g_currentVehicleSeat = nil; 479 480 -- teleport player to our leave position 481 local x,y,z = getWorldPosition(self.leaveNode); 482 483 --[[if self.enteredOnSkis then 484 g_scenario.player.skierController:moveToFeet(x,y,z); 485 g_scenario.player.skierController:setIsActive(true); 486 else 487 g_scenario.player:moveToFeet(x,y,z); 488 --end; 489 end;
VehicleSeat:selectCamera(slotNo)
Activates the specified camera slot slotNo
(int, range 1-4).
493 function VehicleSeat:selectCamera(slotNo) 494 if self.selectedSlot == slotNo then 495 -- turn one further 496 local slot = self.cameraSlots[slotNo]; 497 self.selectedIndex = self.selectedIndex + 1; 498 self.selectedIndex = self.selectedIndex > #slot and 1 or self.selectedIndex; 499 self.activeCamera = slot[self.selectedIndex]; 500 self.activeCamera:activate(); 501 502 503 elseif self.cameraSlots[slotNo] ~= nil then 504 -- switch to that one 505 local slot = self.cameraSlots[slotNo]; 506 self.selectedSlot = slotNo; 507 self.selectedIndex = 1; 508 self.activeCamera = slot[self.selectedIndex]; 509 self.activeCamera:activate(); 510 end; 511 512 self.isInterieurCamera = self.activeCamera.isInterieur; 513 514 -- change player character depending on the camera 515 if self.currentUser ~= nil then 516 setActive(self.currentUser.playerCharacterSit, not self.isInterieurCamera); 517 518 Animator.setTrigger(self.currentUser.playerCharacterSit, self.characterPose); 519 end; 520 end;
VehicleSeat:update(dt)
Called every frame to update the seat and the active camera.
524 function VehicleSeat:update(dt) 525 if self.seatActive then 526 527 self.activeCamera:update(dt); 528 self.isInterieurCamera = self.activeCamera.isInterieur; 529 530 -- save the information about interior camera in player 531 if self.currentUser ~= nil then 532 self.currentUser.isInterieurCamera = self.isInterieurCamera; 533 end; 534 535 if not g_GUI:getAnyGuiActive() then 536 if InputMapper:getKeyDown(InputMapper.InterieurCamera) then self:selectCamera(1); 537 elseif InputMapper:getKeyDown(InputMapper.ExterieurCamera) then self:selectCamera(2); 538 elseif InputMapper:getKeyDown(InputMapper.CustomCamera1) then self:selectCamera(3); 539 elseif InputMapper:getKeyDown(InputMapper.CustomCamera2) then self:selectCamera(4); 540 end; 541 542 -- finally check whether we're going to leave 543 if InputMapper:getKeyDown(InputMapper.EnterSeat) then 544 self:localLeaveRequest(false); 545 end; 546 547 if self.updateCallback ~= nil then 548 self.updateCallback(self.updateCallbackObject, dt); 549 end; 550 end; 551 end; 552 end;
VehicleSeat:fixedUpdate(dt)
Called upon physics update.
556 function VehicleSeat:fixedUpdate(dt) 557 if self.seatActive then 558 self.activeCamera:fixedUpdate(dt); 559 end; 560 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.