meta data for this page
Vehicles/VehicleManager.lua
Together with Vehicle, VehicleManager is at the core of all scripts relating to vehicles. It is responsible for managing many features that are shared between all vehicles (such as switching vehicles using the Tab
key and the distribution of various events such as update(dt)
).
34 VehicleManager = VehicleManager or {};
VehicleManager:setup()
Is called upon initialisation of the game. This will also set up SnowmakingManager.
39 function VehicleManager:setup() 40 self.vehicles = {}; 41 self.vehiclesByOrder = {}; 42 self.vehiclesById = {}; 43 self.vehicleTypes = {}; 44 45 self.allowSwitchVehicle = true; 46 self.currentVehicle = nil; -- the vehicle this player is currently in 47 48 self.vehicleSpawnPositons = {}; 49 self.dummyFunction = function() end; 50 51 VehicleManager.vehicleFallbacks = {}; 52 VehicleManager:registerVehicleFallback("default.MarmottaGigaSnow100", "default.TechnoalpinTR10"); 53 54 SnowmakingManager:setup(); 55 end; 56
VehicleManager:newFunction(functionName)
This function will return a new function which calls the function named functionName
(string) for all vehicle scripts of the vehicle it is called on. Check the load()
function of any vehicle script (e.g. RopeWinch) to see how it is used.
59 function VehicleManager:newFunction(functionName) 60 -- returns a function that calls all vehicle scripts 61 62 return function(self, ...) 63 -- call all vehicle scripts 64 65 for _, script in ipairs(self.vehicleScripts) do 66 -- ensure its not nil 67 if script[functionName] ~= nil then 68 script[functionName](self, ...); 69 end; 70 end; 71 end; 72 end; 73
VehicleManager:dummyFunction()
This function will return a dummy function that does not perform any action at all. This is easier than checking the functions against nil in some cases.
77 function VehicleManager:dummyFunction() 78 return self.dummyFunction; 79 end;
VehicleManager:registerVehicleType(typeName, dataTable)
Registers a new vehicle template named typeName
(string). The data regarding this template are stored within template
(table).
87 function VehicleManager:registerVehicleType(typeName, dataTable) 88 self.vehicleTypes[typeName] = dataTable; 89 -- mark this as non-customizable, only if self:loadCustomizations() succeeds, this will be overwritten by true 90 dataTable.isCustomizable = false; 91 if type(dataTable.customizations) == "table" then 92 self:loadCustomizations(typeName, dataTable); 93 94 -- throw a warning if a modder wants to add a customization, but chose the wrong data type 95 elseif dataTable.customizations ~= nil then 96 print("Warning while loading vehicle type " .. tostring(typeName) .. ". Invalid value customizations is a " .. type(dataTable.customizations) .. " (table expected). Customizations will be ignored."); 97 end; 98 end; 99
VehicleManager:registerVehicleFallback(fallbackFrom, fallbackTo)
Registers a new vehicle fallback for the vehicle type fallbackFrom
(string). If this vehicle cannot be found, the game will use the vehicle type fallbackTo
(string) instead. Note that both must be the full vehicle name including mod path, workshop id and asset bundle name.
102 function VehicleManager:registerVehicleFallback(fallbackFrom, fallbackTo) 103 VehicleManager.vehicleFallbacks[fallbackFrom] = fallbackTo; 104 end; 105
VehicleManager:registerVehicle(vehicle)
Registers a new vehicle instance vehicle
(table of the instance).
108 function VehicleManager:registerVehicle(vehicle) 109 -- add this entry to vehicles list 110 -- note: key is actually the vehicle value 111 self.vehicles[vehicle.mainId or vehicle.id] = vehicle; 112 113 -- avoid double entries 114 for n, vhc in ipairs(self.vehiclesByOrder) do 115 if vehicle == vhc then 116 return; 117 end; 118 end; 119 120 table.insert(self.vehiclesByOrder, vehicle); 121 end; 122
VehicleManager:registerVehicleRigidBody(vehicle, id)
124 function VehicleManager:registerVehicleRigidBody(vehicle, id) 125 self.vehiclesById[id] = vehicle; 126 end; 127
VehicleManager:unregisterVehicleRigidBody(id)
129 function VehicleManager:unregisterVehicleRigidBody(id) 130 self.vehiclesById[id] = nil; 131 end; 132
VehicleManager:getVehicleById(id)
Returns the vehicle to which the rigid body id id
(transform id) belongs.
135 function VehicleManager:getVehicleById(id) 136 return self.vehiclesById[id]; 137 end; 138
VehicleManager:getOwnsVehicleOfType(vehicleType, contentPrefix)
Returns true
if the player returns a vehicle of type vehicleType
(string) coming from a mod with contentPrefix contentPrefix
(string). Otherwise returns false
.
141 function VehicleManager:getOwnsVehicleOfType(vehicleType, contentPrefix) 142 for k, v in ipairs(self.vehiclesByOrder) do 143 if v.vehicleType == vehicleType or v.vehicleType == ("default." .. vehicleType) then 144 return true; 145 end; 146 if contentPrefix ~= nil and v.vehicleType == (contentPrefix .. vehicleType) then 147 return true; 148 end; 149 end; 150 return false; 151 end; 152
VehicleManager:unregisterVehicle(vehicle)
Unregisters the vehicle instance vehicle
(table of the instance). This is called in Vehicle:destroy()
(see Vehicle).
155 function VehicleManager:unregisterVehicle(vehicle) 156 -- delete this entry 157 if vehicle.mainId ~= nil then 158 self.vehicles[vehicle.mainId] = nil; 159 end; 160 if vehicle.id ~= nil then 161 self.vehicles[vehicle.id] = nil; 162 end; 163 164 for n, vhc in ipairs(self.vehiclesByOrder) do 165 if vehicle == vhc then 166 table.remove(self.vehiclesByOrder, n); 167 break; 168 end; 169 end; 170 end; 171
VehicleManager:onEnterVehicle(vehicle)
Is called every time the player enters the vehicle vehicle
(table of the instance).
174 function VehicleManager:onEnterVehicle(vehicle) 175 -- in case we are still sitting in another vehicle, we first need to leave that vehicle 176 if self.currentVehicle ~= nil then 177 -- this is just an additional sanity check that should not be in use after 21/09/2020 any more! 178 self.currentVehicle:handleLeave(g_scenario.player, true); 179 end; 180 self.currentVehicle = vehicle; 181 182 -- reset player controller's parent 183 if g_scenario.player ~= nil then 184 g_scenario.player:setParent(0); 185 end; 186 187 -- micro lag: call this every now and then to refresh the snow system 188 g_scenario:allowMicroLag(); 189 end; 190
VehicleManager:onLeaveVehicle(vehicle)
Is called every time the player leaves the vehicle vehicle
(table of the instance).
193 function VehicleManager:onLeaveVehicle(vehicle) 194 if self.currentVehicle == vehicle then 195 self.currentVehicle = nil; 196 end; 197 end; 198
VehicleManager:switchVehicle(delta, player)
Is called every time the player wants to switch vehicles, e.g. by pressing the Tab
key. delta
(eiter larger 0 or less than 0). The function walks through all available vehicles in the given order and activates the next possible one.
If called on a client, the function will trigger a EventRequestSwitchVehicle
, which will let the server execute the code.
203 function VehicleManager:switchVehicle(delta, player) 204 if g_scenario == nil then 205 return; 206 end; 207 208 if g_isClient then 209 EventRequestSwitchVehicle:send(delta); 210 return; 211 end; 212 213 if not self.allowSwitchVehicle or not g_scenario.freeplayMode then 214 return; 215 end; 216 217 -- nil means its the local player 218 if player == nil then 219 player = g_scenario.player; 220 221 if g_GUI:getAnyGuiActive() or player == nil or player:isEditorActive() then 222 return; 223 end; 224 225 end; 226 227 -- this is a bit slow, but simpler in programming 228 local currentIndex = 0; 229 local vehicleCount = 0; 230 local vehicleList = {}; 231 232 for i, vehicle in ipairs(self.vehiclesByOrder) do 233 234 -- count all vehicles that have driver seats 235 if not vehicle.nonTabbable and (vehicle.driverSeat ~= nil or vehicle:getMayEnterOnAnySeat(player)) then 236 vehicleCount = vehicleCount + 1; 237 table.insert(vehicleList, vehicle); 238 end; 239 240 -- determine current vehicle number in that list 241 if vehicle:getIsEnteredAsPassenger(player) and not vehicle:getIsEntered(player) and vehicle:getMayEnter(player) then 242 if vehicle:tryEnter(player) then 243 return; 244 end; 245 246 end; 247 if vehicle:getIsEntered(player) or vehicle:getIsEnteredAsPassenger(player) then 248 currentIndex = vehicleCount; 249 end; 250 end; 251 252 -- fix current index if we're not sitting in a vehicle 253 if currentIndex == 0 then 254 currentIndex = ifelse(delta > 0, 0, 1); 255 end; 256 257 local i = 1; 258 while i <= vehicleCount do 259 -- get the index of the new vehicle 260 local index = currentIndex + i * delta; 261 while index <= 0 do 262 --print("lower " .. index) 263 index = index + vehicleCount; 264 end; 265 while index > vehicleCount do 266 --print("raise " .. index) 267 index = index - vehicleCount; 268 end; 269 270 local vehicle = vehicleList[index]; 271 272 -- try to enter that vehicle 273 if not vehicle.nonTabbable and (vehicle.driverSeat ~= nil or vehicle:getMayEnterOnAnySeat(player)) then 274 -- jump into this vehicle, then quit 275 if vehicle:tryEnter(player) then 276 return; 277 end; 278 end; 279 280 i = i + 1; 281 end; 282 283 -- has not worked -> stay where you are 284 end; 285
VehicleManager:update(...)
This is directly called by the game's update
function. It distributes the update(dt)
call to the currently active vehicle seat.
In Season 2, vehicles receive their update()
event from the entity system and not from the Vehicle Manager any more.
290 function VehicleManager:update(...) 291 -- call this once per frame 292 SnowmakingManager:preUpdate(...); 293 294 -- switch vehicle function 295 if InputMapper:getKeyDown(InputMapper.Vehicle_Switch_Inverse) then 296 -- switch with inverse order 297 self:switchVehicle(-1); 298 299 elseif InputMapper:getKeyDown(InputMapper.Vehicle_Switch) then 300 -- switch to next vehicle 301 self:switchVehicle(1); 302 end; 303 304 if g_currentVehicleSeat ~= nil and g_currentVehicleSeat.update ~= nil then 305 g_currentVehicleSeat:update(...); 306 end; 307 end; 308
VehicleManager:fixedUpdate(...)
This again is called directly by the game's fixedUpdate
function. It always calls the active vehicle seat to allow for smooth camera control.
In Season 2, vehicles receive their fixedUpdate()
event from the entity system and not from the Vehicle Manager any more.
313 function VehicleManager:fixedUpdate(...) 314 if g_currentVehicleSeat ~= nil and g_currentVehicleSeat.fixedUpdate ~= nil then 315 g_currentVehicleSeat:fixedUpdate(...); 316 end; 317 end;
VehicleManager:spawnVehicle(typeName, x,y,z, rx,ry,rz, customizationName, color, isDummy)
Spawns a new vehicle of template name typeName
(string) at position x,y,z
(all float) with rotation rx,ry,rz
(all float in degrees). In case the vehicle can be customized, the customization named customizationName
(optional string) will be used.
321 function VehicleManager:spawnVehicle(typeName, x,y,z, rx,ry,rz, customizationName, color, isDummy) 322 -- parameters for Vehicle:new are returned by getVehicleParams 323 local successful, params = self:getVehicleParams(typeName, customizationName, isDummy, color); 324 325 -- if the vehicle was not found, we need to return a nil value 326 if not successful then 327 return nil; 328 end; 329 330 -- create the vehicle instance 331 local instance = Vehicle:new(unpack(params)); 332 instance.customColors = color; 333 -- spawn the vehicle 334 instance:spawnAt(x,y,z, rx or 0, ry or 0, rz or 0); 335 336 if not isDummy then 337 -- now finally register 338 instance:register(); 339 end; 340 341 return instance; 342 end; 343
VehicleManager:spawnDummyVehicle(typeName, x,y,z, rx,ry,rz, customizationName, customColor)
Spawns a new dummy vehicle of template name typeName
(string) at position x,y,z
(all float) with rotation rx,ry,rz
(all float in degrees). In case the vehicle can be customized, the customization named customizationName
(optional string) will be used. Dummy vehicles will not be functional or registered to any events (e.g. update events). They are used for example if a snow cannon is placed via the placing menu.
347 function VehicleManager:spawnDummyVehicle(typeName, x,y,z, rx,ry,rz, customizationName, customColor) 348 local vehicle = self:spawnVehicle(typeName, x,y,z, rx,ry,rz, customizationName, customColor, true); 349 350 -- if we failed to load the vehicle, quit immediately 351 if vehicle == nil then 352 return nil; 353 end; 354 355 -- if there is a rigidbody, turn collision detection off 356 if Rigidbody.isRigidbody(vehicle.mainId) then 357 Rigidbody.setDetectCollisions(vehicle.mainId, false); 358 end; 359 360 -- disable all child colliders 361 Rigidbody.disableAllColliders(vehicle.mainId); 362 363 return vehicle; 364 end; 365
VehicleManager:getVehicleParams(typeName, customizationName, isDummy, customColors)
Internal use only
368 function VehicleManager:getVehicleParams(typeName, customizationName, isDummy, customColors) 369 -- find the type's data table 370 local dataTable = self:getDataTable(typeName, nil); 371 372 if dataTable == nil then 373 print("Error VehicleManager: attempt to spawn non-existing vehicle with template name " .. tostring(typeName) .. ". Make sure you've installed all mods that are used in this savegame."); 374 return false; 375 end; 376 377 -- load the configuration 378 local mod, bundleId = ModLoader.getModByName(dataTable.modName); 379 380 -- find the correct data table 381 if dataTable.isCustomizable and type(customizationName) == "string" then 382 local customDataTable = dataTable.customizedDataTables[customizationName]; 383 if customDataTable ~= nil then 384 -- this is indeed available 385 dataTable = customDataTable; 386 else 387 -- throw a warning message 388 print("Warning in VehicleManager: attempt to spawn vehicle type '" .. tostring(typeName) .. "' in customization named '" .. tostring(customizationName) .. "'. This customization is not available. The vehicle will be loaded without any customization (might lead to unexpected results)."); 389 end; 390 end; 391 392 return true, { bundleId, typeName, dataTable, isDummy or false, customColors}; 393 end; 394
VehicleManager:getFallbackDatatable(typeName)
This function will be used to return the fallback datatable(saved in 'VehicleManager.vehicleFallbacks') for a vehicle, where the content name has changed but the old name is saved in savegame.
397 function VehicleManager:getFallbackDatatable(typeName) 398 local newTypeName = VehicleManager.vehicleFallbacks[typeName]; 399 return self.vehicleTypes[newTypeName]; 400 end 401
VehicleManager:saveToTable()
Called directly by the scenario when the game is saved. The function passes the call on to each vehicle.
404 function VehicleManager:saveToTable() 405 local vehicles = {}; 406 for k, vehicle in ipairs(VehicleManager.vehiclesByOrder) do 407 table.insert(vehicles, vehicle:saveToTable()); 408 end; 409 return vehicles; 410 end; 411
VehicleManager:loadFromTable(tbl)
Also called directly by the scenario when the game is loaded. The function spawns a new vehicle for each table entry and calls Vehicle:loadFromTable()
on each vehicle.
414 function VehicleManager:loadFromTable(tbl) 415 if tbl == nil then return end; 416 if g_isClient then return end; 417 418 for k, vehicle in ipairs(tbl) do 419 self:loadVehicleFromTable(vehicle); 420 end; 421 end; 422
VehicleManager:loadVehicleFromTable(tbl)
Loads a vehicle from a table.
425 function VehicleManager:loadVehicleFromTable(tbl) 426 if tbl == nil then return; end; 427 if g_isClient then return; end; 428 429 -- type name was called template name before 27/04/2020, but we still need to keep savegames compatible 430 local vehicleType = getNoNil(tbl.vehicleType, tbl.templateName); 431 local vehicle = VehicleManager:spawnVehicle(vehicleType, tbl.px,tbl.py,tbl.pz, tbl.rx,tbl.ry,tbl.rz, tbl.customizationName, tbl.customColors, false); 432 433 -- check this against nil (nil will be returned if the template is invalid) 434 if vehicle ~= nil then 435 vehicle:loadFromTable(tbl); 436 end; 437 438 return vehicle; 439 end; 440
VehicleManager:reloadVehicle(vehicle)
Allows to reload a vehicle on-the-fly, thereby applying changes made to the data table during runtime (if available).
443 function VehicleManager:reloadVehicle(vehicle) 444 assert(g_isMaster, "Not allowed on network clients. Reload must be performed by host."); 445 local tbl = vehicle:saveToTable(); 446 vehicle:onDestroy(); 447 448 return self:loadVehicleFromTable(tbl); 449 end; 450
VehicleManager:addSpawnPosition(id, customVehicleRotation)
Permanently adds a spawn position to the game. Any time vehicles are bought or resetted, they will be placed on the first available spawn position.
453 function VehicleManager:addSpawnPosition(id, customVehicleRotation) 454 local pos = {}; 455 pos.startPosition = VectorUtils.getWorldPosition(id); 456 pos.endPosition = VectorUtils.getWorldPosition(getChildAt(id, 0)); 457 pos.width = (pos.endPosition - pos.startPosition):magnitude(); 458 pos.direction = (pos.endPosition - pos.startPosition):normalized(); 459 460 x,y,z = getWorldRotation(id); 461 pos.ry = y; 462 463 pos.vehicleRotation = customVehicleRotation or y; 464 465 table.insert(self.vehicleSpawnPositons, pos); 466 end; 467
VehicleManager:newTempSpawnPosition(posBegin, posEnd, ry, customVehicleRotation)
Temporarily creates a new spawn position, e.g. if a tutorial mission is active.
470 function VehicleManager:newTempSpawnPosition(posBegin, posEnd, ry, customVehicleRotation) 471 local place = {}; 472 place.startPosition = posBegin; 473 place.endPosition = posEnd; 474 place.width = (posEnd - posBegin):magnitude(); 475 place.direction = (posEnd - posBegin):normalized(); 476 477 place.ry = ry or 0; 478 place.vehicleRotation = customVehicleRotation or place.ry; 479 480 return place; 481 end; 482
VehicleManager:addSpawnPositionOverride(place)
Temporarily adds a spawn position to the overrides. Any time a vehicle is bought or resetted, override spawn positions will be preferred over permanent spawn positions.
485 function VehicleManager:addSpawnPositionOverride(place) 486 if self.spawnPositionOverrides == nil then 487 self.spawnPositionOverrides = {}; 488 end; 489 490 table.insert(self.spawnPositionOverrides, place); 491 end; 492
VehicleManager:cleanupSpawnPositionOverrides()
Removes any temporary spawn position overrides.
495 function VehicleManager:cleanupSpawnPositionOverrides() 496 self.spawnPositionOverrides = nil; 497 end; 498
VehicleManager:findPosition(width, length)
Returns the first suitable spawn position (spawn position overrides first, then permanent spawn positions).
501 function VehicleManager:findPosition(width, length) 502 local positions = {}; 503 504 if self.spawnPositionOverrides ~= nil then 505 Utils.copyAndInsert(self.spawnPositionOverrides, positions); 506 end; 507 508 Utils.copyAndInsert(self.vehicleSpawnPositons, positions); 509 510 511 local height = 5; 512 width, length = width+2.5, length+1; -- leave a minimum gap 513 514 for k, place in ipairs(positions) do 515 -- do some box casts there 516 517 for i=width/2, place.width-width/2, 1 do 518 local p = place.startPosition + place.direction:multiply(i); 519 p.y = Utils.sampleTerrainHeight(p.x, p.z) + height/2; 520 521 local isFull = Utils.checkBox(Vector3:new(p.x, p.y, p.z), Vector3:new(width, height, length), place.ry); 522 523 if not isFull then 524 return p.x,p.y,p.z, place.vehicleRotation; 525 end; 526 end; 527 end; 528 529 if #positions <= 0 and g_scenario.player ~= nil and g_scenario.player.isActive then 530 -- there are no spawn positions within the map! 531 -- therefore spawn at player position 532 local p = VectorUtils.getWorldPosition(g_scenario.player.transformId); 533 p.y = Utils.sampleTerrainHeight(p.x, p.z) + height/2; 534 535 local isFull = Utils.checkBox(Vector3:new(p.x, p.y, p.z), Vector3:new(width, height, length), 0, (2^32) - 1 - 2^19 - 2^2); 536 537 -- return this as backup position 538 if not isFull then 539 local rx,ry,rz = getWorldRotation(g_scenario.player.transformId); 540 return p.x,p.y,p.z, ry, true; 541 end; 542 end; 543 544 -- nothing found if we actually arrive here (so nothing is returned) 545 end; 546
VehicleManager:addMaintenanceExpenses(dayShare)
Charges maintenance expenses for all vehicles. The daily maintenance costs are multiplied by the factor dayShare
(float, share of the day passed since the last call).
549 function VehicleManager:addMaintenanceExpenses(dayShare) 550 -- add maintenance cost for each vehicle 551 for k, v in pairs(self.vehiclesByOrder) do 552 local cost = v:getMaintenanceCost() or 0; 553 g_scenario.accounting:addExpense("vehicles", -cost*dayShare); 554 end; 555 end; 556
VehicleManager:vehicleOutOfBounds(vehicle)
Gets called if vehicle
(table of the vehicle instance) is out of bounds. (Added in Season 1 Update 7.1)
559 function VehicleManager:vehicleOutOfBounds(vehicle) 560 -- vehicle shouldn't be sold, if the cursor points outside the map 561 if vehicle ~= nil then 562 local soldFor = vehicle:sell(); 563 564 if vehicle.dataTable ~= nil then 565 vehicleName = l10n.getDollar(vehicle.dataTable.title); 566 end; 567 568 g_scenario.notifications:add(Notifications.WARNING, 569 l10n.format("msg_vehicleOutOfBounds_title", vehicleName), 570 l10n.format("msg_vehicleOutOfBounds_desc", vehicleName, l10n.formatCurrencyAmount(soldFor, "float")) 571 ); 572 end; 573 end; 574
VehicleManager:loadCustomizations(typeName, dataTable)
Prepares the data tables for all customizations of vehicle type typeName
(string) based on the raw data table dataTable
(table).
577 function VehicleManager:loadCustomizations(typeName, dataTable) 578 if type(dataTable) ~= "table" and type(dataTable.customizations) ~= "table" then 579 return; 580 end; 581 582 -- create copy of data table, because we don't want the customizations in the customized data table 583 local dataTableCopy = TableUtil.deepCopy(dataTable); 584 585 -- mark this as customizable 586 dataTable.customizedDataTables = {}; 587 dataTable.customizedDataTablesOrdered = {}; 588 589 -- force this value to be nil 590 dataTable.customizationName = nil; 591 592 -- get the bundle id 593 local mod, bundleId = ModLoader.getModByName(dataTable.modName); 594 595 -- go through all available customizations 596 for i, v in pairs(dataTable.customizations) do 597 if type(v) ~= "table" then 598 print("Error while loading vehicle type '" .. tostring(typeName) .. "': Invalid customization '" .. tostring(i) .. "', it is a " .. type(v) .. "value (table expected). Skipping this customization."); 599 600 elseif type(v.customizationName) ~= "string" then 601 print("Error while loading vehicle type '" .. tostring(typeName) .. "': each customization must have a customizationName (must be a string)! Skipping invalid customization."); 602 603 elseif dataTable.customizedDataTables[v.customizationName] ~= nil then 604 print("Error while loading vehicle type '" .. tostring(typeName) .. "': Customization name '".. tostring(v.customizationName) .. "' was used twice. Skipping invalid customization."); 605 606 else 607 -- everything is okay, let's load the customization 608 609 -- v is the table that contains all changes to the original vehicle's dataTable 610 -- create a new data table containing all information relevant to the vehicle 611 local customDataTable = self:constructCustomDataTable(TableUtil.deepCopy(dataTableCopy), v); 612 613 -- force the correct content name 614 customDataTable.contentName = dataTable.contentName; 615 customDataTable.customizations = nil; 616 customDataTable.originalDataTable = dataTable; 617 618 -- load a sprite if necessary 619 if customDataTable.previewFilename ~= nil and customDataTable.previewFilename ~= dataTable.previewFilename then 620 customDataTable.previewSprite = Utils.loadBundleSprite(bundleId, customDataTable.previewFilename); 621 end; 622 623 --set width, height, length to the customiziation 624 customDataTable.width = getNoNil(customDataTable.width, 2); 625 customDataTable.height = getNoNil(customDataTable.height, 5); 626 customDataTable.length = getNoNil(customDataTable.length, 2); 627 628 -- note that customDataTable.customizationName was implicitly assigned! Yay! 629 dataTable.customizedDataTables[v.customizationName] = customDataTable; 630 table.insert(dataTable.customizedDataTablesOrdered, customDataTable); 631 632 -- store the id inside the ordered table 633 customDataTable.internalCustomizationId = #dataTable.customizedDataTablesOrdered; 634 end; 635 end; 636 637 -- everything went well up to now, therefore enable customizing 638 dataTable.isCustomizable = true; 639 -- the data table was changed by reference, so the return value does not need to be used 640 return dataTable; 641 end; 642
VehicleManager:constructCustomDataTable(dataTable, customDataTable)
Internal use only
645 function VehicleManager:constructCustomDataTable(dataTable, customDataTable) 646 if customDataTable == nil then 647 return dataTable; 648 end; 649 650 -- custom data table is not nil, therefore we need to care about its data type 651 if dataTable == nil or type(customDataTable) ~= "table" then 652 return customDataTable; 653 end; 654 655 -- custom data table is a table, therefore we need to go through each item 656 -- also, dataTable cannot be nil (since this was checked above already) 657 658 for k, v in pairs(customDataTable) do 659 dataTable[k] = self:constructCustomDataTable(dataTable[k], v); 660 end; 661 662 return dataTable; 663 end; 664
VehicleManager:getDataTable(vehicleType, contentPrefix)
Returns the dataTable
(table) of vehicle type vehicleType
(string) from a mod with content prefix contentPrefix
(string). If the data table is not found, nil
will be returned.
667 function VehicleManager:getDataTable(vehicleType, contentPrefix) 668 return Utils.getDataTable(VehicleManager.vehicleTypes, VehicleManager.vehicleFallbacks, vehicleType, contentPrefix); 669 end; 670
VehicleManager:getVehicleTypeName(vehicleType, contentPrefix)
Returns the display name (string) of vehicle type vehicleType
(string) from a mod with content prefix contentPrefix
(string). If the data table is not found, nil
will be returned.
673 function VehicleManager:getVehicleTypeName(vehicleType, contentPrefix) 674 if vehicleType == nil then 675 return nil; 676 end; 677 678 local dataTable = VehicleManager:getDataTable(vehicleType, contentPrefix); 679 if dataTable == nil then 680 return nil; 681 end; 682 683 return l10n.getDollar(dataTable.title or ""); 684 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.