Script v1_7_1_0
- AI
- Animals
- Collections
- Contracts
- Debug
- Economy
- Elements
- EnvironmentalScore
- Errors
- Events
- GUI
- Handtools
- Hud
- I3d
- Input
- Jobs
- Maps
- Materials
- Misc
- Objects
- Parameters
- Placeables
- Placement
- Player
- Shop
- Sounds
- Specialization
- Specializations
- AIConveyorBelt
- AIDrivable
- AIFieldWorker
- AIImplement
- AIJobVehicle
- AIVehicle
- AIVehicleObstacle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- AutoLoader
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BaseMaterial
- BigBag
- BunkerSiloCompacter
- BunkerSiloInteractor
- CCTDrivable
- Combine
- ConnectionHoses
- ConveyorBelt
- Cover
- CrabSteering
- Crawlers
- CropSensor
- Cultivator
- Cutter
- Cylindered
- CylinderedFoldable
- Dashboard
- Dischargeable
- Drivable
- DynamicallyLoadedParts
- DynamicMountAttacher
- Enterable
- ExtendedAIVehicle
- ExtendedCombine
- ExtendedMotorized
- ExtendedMower
- ExtendedSowingMachine
- ExtendedSprayer
- ExtendedWearable
- FertilizingCultivator
- FertilizingSowingMachine
- FillTriggerVehicle
- FillUnit
- FillVolume
- Foldable
- FoliageBending
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- GroundAdjustedNodes
- GroundReference
- HeadlandAnimation
- Honk
- HookLiftContainer
- HookLiftTrailer
- IKChains
- InlineWrapper
- JigglingParts
- Leveler
- LicensePlates
- Lights
- LivestockTrailer
- Locomotive
- LogGrab
- ManureBarrel
- ManureSensor
- MixerWagon
- Motorized
- Mountable
- Mower
- Mulcher
- MultipleItemPurchase
- Pallet
- Pickup
- Pipe
- PlaceableAI
- PlaceableAnimatedObjects
- PlaceableBeehive
- PlaceableBeehivePalletSpa...
- PlaceableBunkerSilo
- PlaceableBuyingStation
- PlaceableCartridgePlayer
- PlaceableChargingStation
- PlaceableClearAreas
- PlaceableColorable
- PlaceableDeletedNodes
- PlaceableDoghouse
- PlaceableDynamicallyLoade...
- PlaceableFarmhouse
- PlaceableFence
- PlaceableFoliageAreas
- PlaceableGreenhouse
- PlaceableHighPressureWash...
- PlaceableHotspots
- PlaceableHusbandry
- PlaceableHusbandryAnimals
- PlaceableHusbandryFeeding...
- PlaceableHusbandryFence
- PlaceableHusbandryFood
- PlaceableHusbandryLiquidM...
- PlaceableHusbandryMilk
- PlaceableHusbandryPallets
- PlaceableHusbandryStraw
- PlaceableHusbandryWater
- PlaceableIncomePerHour
- PlaceableIndoorAreas
- PlaceableInfoTrigger
- PlaceableLeveling
- PlaceableLights
- PlaceableManureHeap
- PlaceablePlacement
- PlaceableProductionPoint
- PlaceableSellingStation
- PlaceableSilo
- PlaceableSiloExtension
- PlaceableSolarPanels
- PlaceableTipOcclusionArea...
- PlaceableTrainSystem
- PlaceableTriggerMarkers
- PlaceableVine
- PlaceableWardrobe
- PlaceableWeatherStation
- PlaceableWeighingStation
- PlaceableWindTurbine
- PlaceableWorkshop
- Plow
- PlowPacker
- PowerConsumer
- PowerTakeOffs
- PrecisionFarmingStatistic
- PushHandTool
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- Rideable
- RidgeMarker
- Roller
- Ropes
- RTKStation
- SaltSpreader
- SemiTrailerFront
- Shovel
- SlopeCompensation
- SmartAttach
- SoilSampler
- SowingMachine
- SpeedRotatingParts
- SplineVehicle
- Sprayer
- StonePicker
- StrawBlower
- StumpCutter
- SupportVehicle
- Suspensions
- Tedder
- TensionBeltObject
- TensionBelts
- TestAreas
- TipOccluder
- Trailer
- TreePlanter
- TreeSaplingPallet
- TreeSaw
- TurnOnVehicle
- VariableWorkWidth
- VehicleSettings
- VineCutter
- VineDetector
- VinePrepruner
- Washable
- WaterTrailer
- Wearable
- Weeder
- WeedSpotSpray
- Wheels
- WindBending
- Windrower
- Wipers
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkMode
- WorkParticles
- StateMachine
- Statistics
- Tasks
- Triggers
- Utils
- Vehicles
Engine v1_7_1_0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- general
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- NoteNode
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- VoiceChat
- XML
Foundation Reference
PlaceableTrainSystem
DescriptionSpecialization for placeablesFunctions
- addSplinePositionUpdateListener
- createVehicles
- finalizeTrain
- getCanBeRented
- getElectricitySpline
- getElectricitySplineLength
- getIsRented
- getIsTrainInDriveableRange
- getLengthSplineTime
- getNeedDayChanged
- getSpline
- getSplineLength
- getSplineTime
- gsIsTrainFilled
- loadFromXMLFile
- onDayChanged
- onDelete
- onDeleteObject
- onFinalizePlacement
- onLoad
- onReadStream
- onReadUpdateStream
- onSellGoodsQuestion
- onUpdate
- onWriteStream
- onWriteUpdateStream
- prerequisitesPresent
- railroadVehicleLoaded
- registerEventListeners
- registerFunctions
- registerOverwrittenFunctions
- registerSavegameXMLPaths
- registerXMLPaths
- removeSplinePositionUpdateListener
- rentRailroad
- returnRailroad
- saveToXMLFile
- sellGoods
- setIsTrainTabbable
- setSplineTime
- toggleRent
- updateDriveableState
- updateTrainLength
- updateTrainPositionByLocomotiveSpeed
- updateTrainPositionByLocomotiveSplinePosition
addSplinePositionUpdateListener
DescriptionDefinitionaddSplinePositionUpdateListener()Code
766 | function PlaceableTrainSystem:addSplinePositionUpdateListener(listener) |
767 | if listener ~= nil then |
768 | local spec = self.spec_trainSystem |
769 | table.addElement(spec.splinePositionUpdateListener, listener) |
770 | end |
771 | end |
createVehicles
DescriptionDefinitioncreateVehicles()Code
621 | function PlaceableTrainSystem:createVehicles() |
622 | local spec = self.spec_trainSystem |
623 | if spec.vehicleIdsToLoad ~= nil and #spec.vehicleIdsToLoad > 0 then |
624 | for k, id in ipairs(spec.vehicleIdsToLoad) do |
625 | local vehicle = g_currentMission.savegameIdToVehicle[id] |
626 | if vehicle ~= nil then |
627 | if vehicle.setTrainSystem == nil then |
628 | --#debug Logging.devWarning("Vehicle '%s' (savegameId %d) is not a railroad vehicle", vehicle:getName(), id) |
629 | --#debug printCallstack() |
630 | else |
631 | vehicle:setTrainSystem(self) |
632 | vehicle.trainVehicleIndex = k |
633 | table.insert(spec.railroadVehicles, vehicle) |
634 | end |
635 | end |
636 | end |
637 | |
638 | self:finalizeTrain(false) |
639 | else |
640 | for k, filename in ipairs(spec.vehiclesToLoad) do |
641 | filename = Utils.getFilename(filename, spec.baseDirectory) |
642 | spec.numVehiclesToLoad = spec.numVehiclesToLoad + 1 |
643 | |
644 | local arguments = { |
645 | filename = filename, |
646 | vehicleIndex = k |
647 | } |
648 | VehicleLoadingUtil.loadVehicle(filename, {x=0, z=0, yOffset=0}, true, 0, Vehicle.PROPERTY_STATE_NONE, AccessHandler.EVERYONE, nil, nil, spec.railroadVehicleLoaded, self, arguments) |
649 | end |
650 | |
651 | end |
652 | spec.vehiclesToLoad = {} |
653 | end |
finalizeTrain
DescriptionDefinitionfinalizeTrain()Code
678 | function PlaceableTrainSystem:finalizeTrain(attachVehicles) |
679 | local spec = self.spec_trainSystem |
680 | |
681 | table.sort(spec.railroadVehicles, function(a, b) |
682 | return a.trainVehicleIndex < b.trainVehicleIndex |
683 | end) |
684 | |
685 | local lastVehicle = nil |
686 | spec.rootLocomotive = nil |
687 | for _,railroadVehicle in ipairs(spec.railroadVehicles) do |
688 | railroadVehicle:addDeleteListener(self) |
689 | |
690 | if spec.rootLocomotive == nil and railroadVehicle.startAutomatedTrainTravel ~= nil then |
691 | spec.rootLocomotive = railroadVehicle |
692 | end |
693 | |
694 | if attachVehicles and lastVehicle ~= nil then |
695 | lastVehicle:attachImplement(railroadVehicle, 1, 1, true) |
696 | end |
697 | |
698 | lastVehicle = railroadVehicle |
699 | end |
700 | |
701 | self:updateTrainLength(spec.startSplineTime) |
702 | self:setIsTrainTabbable(spec.isRented and g_currentMission:getFarmId() == spec.rentFarmId) |
703 | end |
getCanBeRented
DescriptionDefinitiongetCanBeRented()Code
895 | function PlaceableTrainSystem:getCanBeRented(farmId) |
896 | local spec = self.spec_trainSystem |
897 | |
898 | if spec.isRented then |
899 | if spec.rentFarmId ~= farmId then |
900 | return false |
901 | end |
902 | end |
903 | |
904 | return true |
905 | end |
getElectricitySpline
DescriptionDefinitiongetElectricitySpline()Code
925 | function PlaceableTrainSystem:getElectricitySpline() |
926 | local spec = self.spec_trainSystem |
927 | return spec.electricitySpline |
928 | end |
getElectricitySplineLength
DescriptionDefinitiongetElectricitySplineLength()Code
932 | function PlaceableTrainSystem:getElectricitySplineLength() |
933 | local spec = self.spec_trainSystem |
934 | return spec.electricitySplineLength or 0 |
935 | end |
getIsRented
DescriptionDefinitiongetIsRented()Code
888 | function PlaceableTrainSystem:getIsRented() |
889 | local spec = self.spec_trainSystem |
890 | return spec.isRented |
891 | end |
getIsTrainInDriveableRange
DescriptionDefinitiongetIsTrainInDriveableRange()Code
725 | function PlaceableTrainSystem:getIsTrainInDriveableRange() |
726 | return self.spec_trainSystem.lastIsInDriveableRange |
727 | end |
getLengthSplineTime
DescriptionDefinitiongetLengthSplineTime()Code
945 | function PlaceableTrainSystem:getLengthSplineTime() |
946 | local spec = self.spec_trainSystem |
947 | return spec.trainLengthSplineTime |
948 | end |
getNeedDayChanged
DescriptionDefinitiongetNeedDayChanged()Code
939 | function PlaceableTrainSystem:getNeedDayChanged(superFunc) |
940 | return true |
941 | end |
getSpline
DescriptionDefinitiongetSpline()Code
952 | function PlaceableTrainSystem:getSpline() |
953 | local spec = self.spec_trainSystem |
954 | return spec.spline |
955 | end |
getSplineLength
DescriptionDefinitiongetSplineLength()Code
918 | function PlaceableTrainSystem:getSplineLength() |
919 | local spec = self.spec_trainSystem |
920 | return spec.splineLength |
921 | end |
getSplineTime
DescriptionDefinitiongetSplineTime()Code
731 | function PlaceableTrainSystem:getSplineTime() |
732 | return self.spec_trainSystem.splineTime |
733 | end |
gsIsTrainFilled
DescriptionDefinitiongsIsTrainFilled()Code
1032 | function PlaceableTrainSystem:gsIsTrainFilled() |
1033 | local spec = self.spec_trainSystem |
1034 | for _,railroadVehicle2 in ipairs(spec.railroadVehicles) do |
1035 | if railroadVehicle2.getFillUnits ~= nil then |
1036 | local fillUnits = railroadVehicle2:getFillUnits() |
1037 | for fillUnitIndex, fillUnit in ipairs(fillUnits) do |
1038 | if fillUnit.fillLevel > 0 then |
1039 | return true |
1040 | end |
1041 | end |
1042 | end |
1043 | end |
1044 | |
1045 | return false |
1046 | end |
loadFromXMLFile
DescriptionDefinitionloadFromXMLFile()Code
440 | function PlaceableTrainSystem:loadFromXMLFile(xmlFile, key) |
441 | local spec = self.spec_trainSystem |
442 | |
443 | xmlFile:iterate(key .. ".railroadObjects", function(_, railroadKey) |
444 | local index = xmlFile:getValue(railroadKey.."#index") |
445 | if index ~= nil then |
446 | local object = spec.railroadObjects[index] |
447 | if object ~= nil then |
448 | object:loadFromXMLFile(xmlFile, railroadKey) |
449 | end |
450 | end |
451 | end) |
452 | |
453 | spec.isRented = xmlFile:getValue(key.."#isRented", spec.isRented) |
454 | spec.rentFarmId = xmlFile:getValue(key.."#rentFarmId", spec.rentFarmId) |
455 | spec.lastRentFarmId = spec.rentFarmId |
456 | spec.currentPrice = xmlFile:getValue(key.."#currentPrice", spec.currentPrice) |
457 | |
458 | spec.startSplineTime = SplineUtil.getValidSplineTime(xmlFile:getValue(key.."#splineTime") or 0) |
459 | |
460 | spec.vehicleIdsToLoad = {} |
461 | local i = 0 |
462 | while true do |
463 | local vehicleKey = string.format("%s.railroadVehicle(%d)", key, i) |
464 | if not xmlFile:hasProperty(vehicleKey) then |
465 | break |
466 | end |
467 | |
468 | local vehicleId = xmlFile:getValue(vehicleKey.."#vehicleId") |
469 | if vehicleId ~= nil then |
470 | table.insert(spec.vehicleIdsToLoad, vehicleId) |
471 | end |
472 | |
473 | i = i + 1 |
474 | end |
475 | end |
onDayChanged
DescriptionDefinitiononDayChanged()Code
875 | function PlaceableTrainSystem:onDayChanged() |
876 | if self.isServer then |
877 | local spec = self.spec_trainSystem |
878 | if spec.currentPrice > 0 then |
879 | g_currentMission:addMoney(-spec.currentPrice, spec.rentFarmId, MoneyType.LEASING_COSTS, true) |
880 | g_currentMission:showMoneyChange(MoneyType.LEASING_COSTS, nil, false, spec.rentFarmId) |
881 | spec.currentPrice = 0 |
882 | end |
883 | end |
884 | end |
onDelete
DescriptionDefinitiononDelete()Code
290 | function PlaceableTrainSystem:onDelete() |
291 | local spec = self.spec_trainSystem |
292 | |
293 | if spec.railroadObjects ~= nil then |
294 | for _, object in ipairs(spec.railroadObjects) do |
295 | object:delete() |
296 | end |
297 | end |
298 | |
299 | if spec.railroadVehicles ~= nil then |
300 | for _, vehicle in ipairs(spec.railroadVehicles) do |
301 | vehicle.trainSystem = nil |
302 | end |
303 | end |
304 | |
305 | g_currentMission:removeTrainSystem(self) |
306 | end |
onDeleteObject
DescriptionDefinitiononDeleteObject()Code
909 | function PlaceableTrainSystem:onDeleteObject(object) |
910 | local spec = self.spec_trainSystem |
911 | if table.removeElement(spec.railroadVehicles, object) then |
912 | self:updateTrainLength(spec.splineTime) |
913 | end |
914 | end |
onFinalizePlacement
DescriptionDefinitiononFinalizePlacement()Code
310 | function PlaceableTrainSystem:onFinalizePlacement() |
311 | local spec = self.spec_trainSystem |
312 | |
313 | if spec.railroadCrossings ~= nil then |
314 | for _, railroadCrossing in ipairs(spec.railroadCrossings) do |
315 | railroadCrossing:findBlockingPositions() |
316 | end |
317 | end |
318 | |
319 | for _, object in ipairs(spec.railroadObjects) do |
320 | if object.setSplineTimeByPosition ~= nil then |
321 | object:setSplineTimeByPosition(object.nearestTime, spec.splineLength) |
322 | end |
323 | if object.onSplinePositionTimeUpdate ~= nil then |
324 | object:onSplinePositionTimeUpdate(spec.splineTime, spec.splineEndTime) |
325 | end |
326 | end |
327 | |
328 | g_currentMission:addTrainSystem(self) |
329 | |
330 | if g_currentMission.isMissionStarted then |
331 | self:createVehicles() |
332 | else |
333 | g_messageCenter:subscribeOneshot(MessageType.LOADED_ALL_SAVEGAME_VEHICLES, self.createVehicles, self, {}) |
334 | end |
335 | end |
onLoad
DescriptionCalled on loadingDefinition
onLoad(table savegame)Arguments
table | savegame | savegame |
116 | function PlaceableTrainSystem:onLoad(savegame) |
117 | local spec = self.spec_trainSystem |
118 | |
119 | spec.splineTime = -1 |
120 | spec.splineTimeSent = spec.splineTime |
121 | spec.splineEndTime = 0 |
122 | spec.trainLengthSplineTime = 0 |
123 | spec.splinePositionUpdateListener = {} |
124 | spec.startSplineTime = spec.startSplineTime or 0 |
125 | spec.railroadVehicles = {} |
126 | spec.trainLength = 0 |
127 | spec.dirtyFlag = self:getNextDirtyFlag() |
128 | spec.stationDirtyFlag = self:getNextDirtyFlag() |
129 | spec.networkTimeInterpolator = InterpolationTime.new(1.2) |
130 | spec.networkSplineTimeInterpolator = InterpolatorValue.new(0) |
131 | |
132 | spec.isRented = false |
133 | spec.rentFarmId = FarmManager.SPECTATOR_FARM_ID |
134 | spec.lastRentFarmId = FarmManager.SPECTATOR_FARM_ID |
135 | spec.currentPrice = 0 |
136 | spec.rentPricePerHour = self.xmlFile:getValue("placeable.trainSystem.rent#pricePerHour", 0) |
137 | spec.rentPricePerMS = spec.rentPricePerHour / 60 / 60 / 1000 |
138 | |
139 | spec.rootLocomotive = nil |
140 | |
141 | spec.spline = self.xmlFile:getValue("placeable.trainSystem.spline#node", nil, self.components, self.i3dMappings) |
142 | if spec.spline == nil then |
143 | Logging.xmlError(self.xmlFile, "Missing spline node!") |
144 | self:setLoadingState(Placeable.LOADING_STATE_ERROR) |
145 | return |
146 | end |
147 | |
148 | if not getHasClassId(getGeometry(spec.spline), ClassIds.SPLINE) then |
149 | Logging.xmlError(self.xmlFile, "Given node is not a spline!") |
150 | self:setLoadingState(Placeable.LOADING_STATE_ERROR) |
151 | return |
152 | end |
153 | |
154 | if not getIsSplineClosed(spec.spline) then |
155 | Logging.xmlError(self.xmlFile, "Train spline is not closed. Open splines are not supported!") |
156 | self:setLoadingState(Placeable.LOADING_STATE_ERROR) |
157 | return |
158 | end |
159 | |
160 | spec.splineLength = getSplineLength(spec.spline) |
161 | spec.splineYOffset = self.xmlFile:getValue("placeable.trainSystem.spline#splineYOffset", 0.0) |
162 | |
163 | spec.splineDriveRange = {0, 1} |
164 | |
165 | spec.drivingRangeStart = self.xmlFile:getValue("placeable.trainSystem.drivingRange#startNode", nil, self.components, self.i3dMappings) |
166 | spec.drivingRangeEnd = self.xmlFile:getValue("placeable.trainSystem.drivingRange#endNode", nil, self.components, self.i3dMappings) |
167 | spec.drivingRangeSellingStationId = self.xmlFile:getValue("placeable.trainSystem.drivingRange#sellingStationId") |
168 | |
169 | spec.textDriveInfo = g_i18n:getText("ui_infoTrainDrive") |
170 | spec.textSellQuestion = g_i18n:getText("ui_questionTrainSellGoods") |
171 | |
172 | spec.hasLimitedRange = false |
173 | if spec.drivingRangeStart ~= nil and spec.drivingRangeEnd ~= nil then |
174 | local nearestDistanceStart = math.huge |
175 | local nearestDistanceEnd = math.huge |
176 | for i=0, 1, 0.5 / spec.splineLength do |
177 | local sx, sy, sz = getSplinePosition(spec.spline, i) |
178 | |
179 | local x1, y1, z1 = getWorldTranslation(spec.drivingRangeStart) |
180 | local distance1 = MathUtil.vector3Length(sx-x1, sy-y1, sz-z1) |
181 | if distance1 < nearestDistanceStart then |
182 | nearestDistanceStart = distance1 |
183 | spec.splineDriveRange[1] = i |
184 | end |
185 | |
186 | local x2, y2, z2 = getWorldTranslation(spec.drivingRangeEnd) |
187 | local distance2 = MathUtil.vector3Length(sx-x2, sy-y2, sz-z2) |
188 | if distance2 < nearestDistanceEnd then |
189 | nearestDistanceEnd = distance2 |
190 | spec.splineDriveRange[2] = i |
191 | end |
192 | end |
193 | |
194 | if spec.splineDriveRange[1] > spec.splineDriveRange[2] then |
195 | local secondValue = spec.splineDriveRange[2] |
196 | spec.splineDriveRange[2] = spec.splineDriveRange[1] |
197 | spec.splineDriveRange[1] = secondValue |
198 | end |
199 | |
200 | spec.hasLimitedRange = true |
201 | end |
202 | |
203 | spec.sellingStationPlaceable = nil |
204 | spec.sellingStationPlaceableId = nil |
205 | spec.sellingStation = nil |
206 | spec.showDialog = 0 |
207 | spec.showDialogDelay = 0 |
208 | |
209 | spec.lastIsInDriveableRange = true |
210 | spec.lastSplineTime = 0 |
211 | |
212 | spec.electricitySpline = self.xmlFile:getValue("placeable.trainSystem.electricitySpline#node", nil, self.components, self.i3dMappings) |
213 | if spec.electricitySpline ~= nil then |
214 | if getHasClassId(getGeometry(spec.electricitySpline), ClassIds.SPLINE) then |
215 | if getIsSplineClosed(spec.electricitySpline) then |
216 | local sx, _, sz = getSplinePosition(spec.spline, 0) |
217 | local esx, _, esz = getSplinePosition(spec.spline, 0) |
218 | if MathUtil.vector2Length(sx-esx, sz-esz) < 5 then |
219 | spec.electricitySplineLength = getSplineLength(spec.electricitySpline) |
220 | spec.electricitySplineYOffset = self.xmlFile:getValue("placeable.trainSystem.electricitySpline#splineYOffset", 0.0) |
221 | else |
222 | Logging.xmlError(self.xmlFile, "Railroad and electricity spline should almost start at the same x and z positions. Ignoring electricity spline!") |
223 | spec.electricitySpline = nil |
224 | end |
225 | else |
226 | Logging.xmlError(self.xmlFile, "Railroad electricity spline has to be closed. Ignoring electricity spline!") |
227 | spec.electricitySpline = nil |
228 | end |
229 | else |
230 | Logging.xmlError(self.xmlFile, "Given electricitySpline node is not a spline. Ignoring electricity spline!") |
231 | spec.electricitySpline = nil |
232 | end |
233 | end |
234 | |
235 | spec.vehiclesToLoad = {} |
236 | |
237 | if self.isServer then |
238 | self.xmlFile:iterate("placeable.trainSystem.train.vehicle", function(_, baseString) |
239 | local filename = self.xmlFile:getValue(baseString .. "#xmlFilename") |
240 | if filename ~= nil then |
241 | table.insert(spec.vehiclesToLoad, filename) |
242 | end |
243 | end) |
244 | end |
245 | |
246 | spec.railroadObjects = {} |
247 | spec.railroadCrossings = {} |
248 | self.xmlFile:iterate("placeable.trainSystem.railroadCrossings.railroadCrossing", function(_, key) |
249 | local railroadCrossing = RailroadCrossing.new(self.isServer, self.isClient, self, self.rootNode) |
250 | if railroadCrossing:loadFromXML(self.xmlFile, key, self.components, self.i3dMappings) then |
251 | table.insert(spec.railroadCrossings, railroadCrossing) |
252 | table.insert(spec.railroadObjects, railroadCrossing) |
253 | else |
254 | railroadCrossing:delete() |
255 | end |
256 | end) |
257 | |
258 | spec.railroadCallers = {} |
259 | self.xmlFile:iterate("placeable.trainSystem.railroadCallers.railroadCaller", function(_, key) |
260 | local railroadCaller = RailroadCaller.new(self.isServer, self.isClient, self, self.rootNode) |
261 | if railroadCaller:loadFromXML(self.xmlFile, key, self.components, self.i3dMappings) then |
262 | table.insert(spec.railroadCallers, railroadCaller) |
263 | table.insert(spec.railroadObjects, railroadCaller) |
264 | end |
265 | end) |
266 | |
267 | for t=0, 1, 0.5/spec.splineLength do |
268 | local x1, y1, z1 = getSplinePosition(spec.spline, t) |
269 | for _, object in ipairs(spec.railroadObjects) do |
270 | local x2, y2, z2 = getWorldTranslation(object.rootNode) |
271 | local distance = MathUtil.vector3Length(x1-x2, y1-y2, z1-z2) |
272 | if object.nearestDistance == nil then |
273 | object.nearestDistance = distance |
274 | object.nearestTime = t |
275 | else |
276 | if object.nearestDistance > distance then |
277 | object.nearestDistance = distance |
278 | object.nearestTime = t |
279 | end |
280 | end |
281 | end |
282 | end |
283 | |
284 | spec.lastVehicle = nil |
285 | spec.numVehiclesToLoad = 0 |
286 | end |
onReadStream
DescriptionDefinitiononReadStream()Code
339 | function PlaceableTrainSystem:onReadStream(streamId, connection) |
340 | if connection:getIsServer() then |
341 | local spec = self.spec_trainSystem |
342 | spec.railroadVehicleIds = {} |
343 | local numVehicles = streamReadInt8(streamId) |
344 | for i=1,numVehicles do |
345 | spec.railroadVehicleIds[i] = NetworkUtil.readNodeObjectId(streamId) |
346 | end |
347 | |
348 | local splineTime = streamReadFloat32(streamId) |
349 | spec.networkSplineTimeInterpolator:setValue(splineTime) |
350 | spec.networkTimeInterpolator:reset() |
351 | spec.splineTime = splineTime |
352 | |
353 | for _, railroadObject in ipairs(spec.railroadObjects) do |
354 | if railroadObject.readStream ~= nil then |
355 | railroadObject:readStream(streamId, connection) |
356 | end |
357 | end |
358 | |
359 | spec.isRented = streamReadBool(streamId) |
360 | spec.rentFarmId = streamReadUIntN(streamId, FarmManager.FARM_ID_SEND_NUM_BITS) |
361 | |
362 | spec.sellingStationPlaceableId = NetworkUtil.readNodeObjectId(streamId) |
363 | |
364 | self:raiseActive() |
365 | end |
366 | end |
onReadUpdateStream
DescriptionDefinitiononReadUpdateStream()Code
396 | function PlaceableTrainSystem:onReadUpdateStream(streamId, timestamp, connection) |
397 | local spec = self.spec_trainSystem |
398 | if connection:getIsServer() then |
399 | if streamReadBool(streamId) then |
400 | local splineTime = streamReadFloat32(streamId) |
401 | spec.networkTimeInterpolator:startNewPhaseNetwork() |
402 | spec.networkSplineTimeInterpolator:setTargetValue(splineTime) |
403 | |
404 | for _, railroadObject in ipairs(spec.railroadObjects) do |
405 | if railroadObject.readUpdateStream ~= nil then |
406 | railroadObject:readUpdateStream(streamId, timestamp, connection) |
407 | end |
408 | end |
409 | end |
410 | |
411 | if streamReadBool(streamId) then |
412 | spec.sellingStationPlaceableId = NetworkUtil.readNodeObjectId(streamId) |
413 | end |
414 | end |
415 | end |
onSellGoodsQuestion
DescriptionDefinitiononSellGoodsQuestion()Code
1050 | function PlaceableTrainSystem:onSellGoodsQuestion(yes) |
1051 | if yes then |
1052 | g_client:getServerConnection():sendEvent(PlaceableTrainSystemSellEvent.new(self)) |
1053 | end |
1054 | end |
onUpdate
DescriptionDefinitiononUpdate()Code
504 | function PlaceableTrainSystem:onUpdate(dt) |
505 | local spec = self.spec_trainSystem |
506 | |
507 | if not self.finishedFirstUpdate then |
508 | self:setIsTrainTabbable(spec.isRented and g_currentMission:getFarmId() == spec.rentFarmId) |
509 | |
510 | self.finishedFirstUpdate = true |
511 | end |
512 | |
513 | for _, railroadObject in ipairs(spec.railroadObjects) do |
514 | if railroadObject.update ~= nil then |
515 | railroadObject:update(dt) |
516 | end |
517 | end |
518 | |
519 | if spec.isRented then |
520 | spec.currentPrice = spec.currentPrice + spec.rentPricePerMS * dt |
521 | end |
522 | |
523 | if not self.isServer and self.isClient then |
524 | -- load railroadVehicles on client side |
525 | if spec.railroadVehicleIds ~= nil then |
526 | local allVehiclesSynchronized = true |
527 | for index, id in pairs(spec.railroadVehicleIds) do |
528 | local vehicle = NetworkUtil.getObject(id) |
529 | if vehicle == nil or not vehicle:getIsSynchronized() then |
530 | allVehiclesSynchronized = false |
531 | end |
532 | end |
533 | |
534 | if allVehiclesSynchronized then |
535 | spec.rootLocomotive = nil |
536 | |
537 | for index, id in pairs(spec.railroadVehicleIds) do |
538 | local vehicle = NetworkUtil.getObject(id) |
539 | if vehicle ~= nil then |
540 | vehicle:setTrainSystem(self) |
541 | spec.trainLength = spec.trainLength + vehicle:getFrontToBackDistance() |
542 | spec.trainLengthSplineTime = spec.trainLength / spec.splineLength |
543 | table.insert(spec.railroadVehicles, index, vehicle) |
544 | |
545 | if spec.rootLocomotive == nil and vehicle.startAutomatedTrainTravel ~= nil then |
546 | spec.rootLocomotive = vehicle |
547 | end |
548 | end |
549 | spec.railroadVehicleIds[index] = nil |
550 | end |
551 | if next(spec.railroadVehicleIds) == nil then |
552 | spec.railroadVehicleIds = nil |
553 | self:setIsTrainTabbable(spec.isRented and g_currentMission:getFarmId() == spec.rentFarmId) |
554 | end |
555 | end |
556 | end |
557 | |
558 | -- update train position on client |
559 | spec.networkTimeInterpolator:update(dt) |
560 | local interpolationAlpha = spec.networkTimeInterpolator:getAlpha() |
561 | local splineTime = spec.networkSplineTimeInterpolator:getInterpolatedValue(interpolationAlpha) |
562 | splineTime = SplineUtil.getValidSplineTime(splineTime) |
563 | self:updateTrainPositionByLocomotiveSplinePosition(splineTime) |
564 | end |
565 | |
566 | if spec.hasLimitedRange then |
567 | if spec.sellingStationPlaceable == nil then |
568 | if spec.drivingRangeSellingStationId ~= nil then |
569 | for _, placeable in pairs(g_currentMission.placeableSystem.placeables) do |
570 | if placeable.mapBoundId == spec.drivingRangeSellingStationId then |
571 | if placeable.spec_sellingStation ~= nil then |
572 | spec.sellingStationPlaceable = placeable |
573 | spec.sellingStation = placeable.spec_sellingStation.sellingStation |
574 | |
575 | self:raiseDirtyFlags(spec.stationDirtyFlag) |
576 | end |
577 | end |
578 | end |
579 | |
580 | spec.drivingRangeSellingStationId = nil |
581 | end |
582 | end |
583 | |
584 | if spec.sellingStationPlaceable == nil and spec.sellingStationPlaceableId ~= nil then |
585 | local placeable = NetworkUtil.getObject(spec.sellingStationPlaceableId) |
586 | if placeable ~= nil then |
587 | if placeable.spec_sellingStation ~= nil then |
588 | spec.sellingStationPlaceable = placeable |
589 | spec.sellingStation = placeable.spec_sellingStation.sellingStation |
590 | end |
591 | end |
592 | end |
593 | |
594 | if spec.showDialogDelay > 0 then |
595 | spec.showDialogDelay = spec.showDialogDelay - dt |
596 | if spec.showDialogDelay <= 0 then |
597 | local stationName = "UNKNOWN" |
598 | if spec.sellingStationPlaceable ~= nil then |
599 | stationName = spec.sellingStationPlaceable:getName() |
600 | end |
601 | |
602 | local textDriveInfo = string.format(spec.textDriveInfo, stationName) |
603 | local textSellQuestion = string.format(spec.textSellQuestion, stationName) |
604 | |
605 | if spec.showDialog == 2 then |
606 | g_gui:showYesNoDialog({text=textDriveInfo .. "\n\n" .. textSellQuestion, callback=self.onSellGoodsQuestion, target=self}) |
607 | else |
608 | g_gui:showInfoDialog({text=textDriveInfo}) |
609 | end |
610 | |
611 | spec.showDialog = 0 |
612 | end |
613 | end |
614 | end |
615 | |
616 | self:raiseActive() |
617 | end |
onWriteStream
DescriptionDefinitiononWriteStream()Code
370 | function PlaceableTrainSystem:onWriteStream(streamId, connection) |
371 | if not connection:getIsServer() then |
372 | local spec = self.spec_trainSystem |
373 | local numVehicles = #spec.railroadVehicles |
374 | streamWriteInt8(streamId, numVehicles) |
375 | for i=1,numVehicles do |
376 | NetworkUtil.writeNodeObject(streamId, spec.railroadVehicles[i]) |
377 | end |
378 | |
379 | streamWriteFloat32(streamId, spec.splineTimeSent) |
380 | |
381 | for _, railroadObject in ipairs(spec.railroadObjects) do |
382 | if railroadObject.writeStream ~= nil then |
383 | railroadObject:writeStream(streamId, connection) |
384 | end |
385 | end |
386 | |
387 | streamWriteBool(streamId, spec.isRented) |
388 | streamWriteUIntN(streamId, spec.rentFarmId, FarmManager.FARM_ID_SEND_NUM_BITS) |
389 | |
390 | NetworkUtil.writeNodeObject(streamId, spec.sellingStationPlaceable) |
391 | end |
392 | end |
onWriteUpdateStream
DescriptionDefinitiononWriteUpdateStream()Code
419 | function PlaceableTrainSystem:onWriteUpdateStream(streamId, connection, dirtyMask) |
420 | local spec = self.spec_trainSystem |
421 | if not connection:getIsServer() then |
422 | if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlag) ~= 0) then |
423 | streamWriteFloat32(streamId, spec.splineTimeSent) |
424 | |
425 | for _, railroadObject in ipairs(spec.railroadObjects) do |
426 | if railroadObject.writeUpdateStream ~= nil then |
427 | railroadObject:writeUpdateStream(streamId, connection, dirtyMask) |
428 | end |
429 | end |
430 | end |
431 | |
432 | if streamWriteBool(streamId, bitAND(dirtyMask, spec.stationDirtyFlag) ~= 0) then |
433 | NetworkUtil.writeNodeObject(streamId, spec.sellingStationPlaceable) |
434 | end |
435 | end |
436 | end |
prerequisitesPresent
DescriptionChecks if all prerequisite specializations are loadedDefinition
prerequisitesPresent(table specializations)Arguments
table | specializations | specializations |
boolean | hasPrerequisite | true if all prerequisite specializations are loaded |
20 | function PlaceableTrainSystem.prerequisitesPresent(specializations) |
21 | return true |
22 | end |
railroadVehicleLoaded
DescriptionDefinitionrailroadVehicleLoaded()Code
657 | function PlaceableTrainSystem:railroadVehicleLoaded(vehicle, vehicleLoadState, args) |
658 | local filename = args.filename |
659 | local vehicleIndex = args.vehicleIndex |
660 | |
661 | local spec = self.spec_trainSystem |
662 | if vehicle ~= nil and vehicleLoadState == VehicleLoadingUtil.VEHICLE_LOAD_OK then |
663 | vehicle:setTrainSystem(self) |
664 | vehicle.trainVehicleIndex = vehicleIndex |
665 | table.insert(spec.railroadVehicles, vehicle) |
666 | else |
667 | Logging.warning("(%s) Could not create trainsystem vehicle!", filename) |
668 | end |
669 | |
670 | spec.numVehiclesToLoad = spec.numVehiclesToLoad - 1 |
671 | if spec.numVehiclesToLoad == 0 and #spec.vehiclesToLoad == 0 then |
672 | self:finalizeTrain(true) |
673 | end |
674 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
64 | function PlaceableTrainSystem.registerEventListeners(placeableType) |
65 | SpecializationUtil.registerEventListener(placeableType, "onLoad", PlaceableTrainSystem) |
66 | SpecializationUtil.registerEventListener(placeableType, "onDelete", PlaceableTrainSystem) |
67 | SpecializationUtil.registerEventListener(placeableType, "onFinalizePlacement", PlaceableTrainSystem) |
68 | SpecializationUtil.registerEventListener(placeableType, "onReadStream", PlaceableTrainSystem) |
69 | SpecializationUtil.registerEventListener(placeableType, "onWriteStream", PlaceableTrainSystem) |
70 | SpecializationUtil.registerEventListener(placeableType, "onReadUpdateStream", PlaceableTrainSystem) |
71 | SpecializationUtil.registerEventListener(placeableType, "onWriteUpdateStream", PlaceableTrainSystem) |
72 | SpecializationUtil.registerEventListener(placeableType, "onUpdate", PlaceableTrainSystem) |
73 | SpecializationUtil.registerEventListener(placeableType, "onDayChanged", PlaceableTrainSystem) |
74 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
26 | function PlaceableTrainSystem.registerFunctions(placeableType) |
27 | SpecializationUtil.registerFunction(placeableType, "createVehicles", PlaceableTrainSystem.createVehicles) |
28 | SpecializationUtil.registerFunction(placeableType, "railroadVehicleLoaded", PlaceableTrainSystem.railroadVehicleLoaded) |
29 | SpecializationUtil.registerFunction(placeableType, "finalizeTrain", PlaceableTrainSystem.finalizeTrain) |
30 | SpecializationUtil.registerFunction(placeableType, "setIsTrainTabbable", PlaceableTrainSystem.setIsTrainTabbable) |
31 | SpecializationUtil.registerFunction(placeableType, "getIsTrainInDriveableRange", PlaceableTrainSystem.getIsTrainInDriveableRange) |
32 | SpecializationUtil.registerFunction(placeableType, "getSplineTime", PlaceableTrainSystem.getSplineTime) |
33 | SpecializationUtil.registerFunction(placeableType, "setSplineTime", PlaceableTrainSystem.setSplineTime) |
34 | SpecializationUtil.registerFunction(placeableType, "addSplinePositionUpdateListener", PlaceableTrainSystem.addSplinePositionUpdateListener) |
35 | SpecializationUtil.registerFunction(placeableType, "removeSplinePositionUpdateListener", PlaceableTrainSystem.removeSplinePositionUpdateListener) |
36 | SpecializationUtil.registerFunction(placeableType, "updateTrainPositionByLocomotiveSpeed", PlaceableTrainSystem.updateTrainPositionByLocomotiveSpeed) |
37 | SpecializationUtil.registerFunction(placeableType, "updateTrainPositionByLocomotiveSplinePosition", PlaceableTrainSystem.updateTrainPositionByLocomotiveSplinePosition) |
38 | SpecializationUtil.registerFunction(placeableType, "updateTrainLength", PlaceableTrainSystem.updateTrainLength) |
39 | SpecializationUtil.registerFunction(placeableType, "toggleRent", PlaceableTrainSystem.toggleRent) |
40 | SpecializationUtil.registerFunction(placeableType, "getCanBeRented", PlaceableTrainSystem.getCanBeRented) |
41 | SpecializationUtil.registerFunction(placeableType, "rentRailroad", PlaceableTrainSystem.rentRailroad) |
42 | SpecializationUtil.registerFunction(placeableType, "returnRailroad", PlaceableTrainSystem.returnRailroad) |
43 | SpecializationUtil.registerFunction(placeableType, "onDeleteObject", PlaceableTrainSystem.onDeleteObject) |
44 | SpecializationUtil.registerFunction(placeableType, "getIsRented", PlaceableTrainSystem.getIsRented) |
45 | SpecializationUtil.registerFunction(placeableType, "getSplineLength", PlaceableTrainSystem.getSplineLength) |
46 | SpecializationUtil.registerFunction(placeableType, "getElectricitySpline", PlaceableTrainSystem.getElectricitySpline) |
47 | SpecializationUtil.registerFunction(placeableType, "getElectricitySplineLength", PlaceableTrainSystem.getElectricitySplineLength) |
48 | SpecializationUtil.registerFunction(placeableType, "getLengthSplineTime", PlaceableTrainSystem.getLengthSplineTime) |
49 | SpecializationUtil.registerFunction(placeableType, "getSpline", PlaceableTrainSystem.getSpline) |
50 | SpecializationUtil.registerFunction(placeableType, "updateDriveableState", PlaceableTrainSystem.updateDriveableState) |
51 | SpecializationUtil.registerFunction(placeableType, "gsIsTrainFilled", PlaceableTrainSystem.gsIsTrainFilled) |
52 | SpecializationUtil.registerFunction(placeableType, "onSellGoodsQuestion", PlaceableTrainSystem.onSellGoodsQuestion) |
53 | SpecializationUtil.registerFunction(placeableType, "sellGoods", PlaceableTrainSystem.sellGoods) |
54 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
58 | function PlaceableTrainSystem.registerOverwrittenFunctions(placeableType) |
59 | SpecializationUtil.registerOverwrittenFunction(placeableType, "getNeedDayChanged", PlaceableTrainSystem.getNeedDayChanged) |
60 | end |
registerSavegameXMLPaths
DescriptionDefinitionregisterSavegameXMLPaths()Code
102 | function PlaceableTrainSystem.registerSavegameXMLPaths(schema, basePath) |
103 | schema:setXMLSpecializationType("Train") |
104 | schema:register(XMLValueType.FLOAT, basePath .. "#splineTime", "Current spline time") |
105 | schema:register(XMLValueType.BOOL, basePath .. "#isRented", "Is train rented") |
106 | schema:register(XMLValueType.INT, basePath .. "#rentFarmId", "Train is rented by farm") |
107 | schema:register(XMLValueType.FLOAT, basePath .. "#currentPrice", "Current pending rent price") |
108 | schema:register(XMLValueType.INT, basePath .. ".railroadVehicle(?)#vehicleId", "Vehicle id") |
109 | schema:register(XMLValueType.INT, basePath .. ".railroadObjects(?)#index", "Object index") |
110 | schema:setXMLSpecializationType() |
111 | end |
registerXMLPaths
DescriptionDefinitionregisterXMLPaths()Code
78 | function PlaceableTrainSystem.registerXMLPaths(schema, basePath) |
79 | schema:setXMLSpecializationType("Train") |
80 | schema:register(XMLValueType.FLOAT, basePath .. ".trainSystem.rent#pricePerHour", "Rent price per real time hour", 0) |
81 | |
82 | schema:register(XMLValueType.NODE_INDEX, basePath .. ".trainSystem.spline#node", "Spline node") |
83 | schema:register(XMLValueType.FLOAT, basePath .. ".trainSystem.spline#splineYOffset", "Spline Y offset", 0) |
84 | |
85 | schema:register(XMLValueType.NODE_INDEX, basePath .. ".trainSystem.drivingRange#startNode", "Start of range node") |
86 | schema:register(XMLValueType.NODE_INDEX, basePath .. ".trainSystem.drivingRange#endNode", "End of range node") |
87 | schema:register(XMLValueType.STRING, basePath .. ".trainSystem.drivingRange#sellingStationId", "Map bound id of selling station") |
88 | |
89 | schema:register(XMLValueType.NODE_INDEX, basePath .. ".trainSystem.electricitySpline#node", "Electricity spline") |
90 | schema:register(XMLValueType.FLOAT, basePath .. ".trainSystem.electricitySpline#splineYOffset", "Electricity spline Y offset", 0) |
91 | |
92 | schema:register(XMLValueType.STRING, basePath .. ".trainSystem.train.vehicle(?)#xmlFilename", "XMl filename") |
93 | |
94 | RailroadCrossing.registerXMLPaths(schema, basePath .. ".trainSystem.railroadCrossings.railroadCrossing(?)") |
95 | RailroadCaller.registerXMLPaths(schema, basePath .. ".trainSystem.railroadCallers.railroadCaller(?)") |
96 | |
97 | schema:setXMLSpecializationType() |
98 | end |
removeSplinePositionUpdateListener
DescriptionDefinitionremoveSplinePositionUpdateListener()Code
775 | function PlaceableTrainSystem:removeSplinePositionUpdateListener(listener) |
776 | if listener ~= nil then |
777 | local spec = self.spec_trainSystem |
778 | table.removeElement(spec.splinePositionUpdateListener, listener) |
779 | end |
780 | end |
rentRailroad
DescriptionDefinitionrentRailroad()Code
829 | function PlaceableTrainSystem:rentRailroad(farmId, position, noEventSend) |
830 | local spec = self.spec_trainSystem |
831 | spec.isRented = true |
832 | |
833 | spec.rentFarmId = farmId |
834 | spec.lastRentFarmId = farmId |
835 | spec.rootLocomotive:setRequestedSplinePosition(position) |
836 | |
837 | for _, railroadVehicle in ipairs(spec.railroadVehicles) do |
838 | railroadVehicle:setOwnerFarmId(spec.rentFarmId, true) |
839 | end |
840 | |
841 | self:setIsTrainTabbable(g_currentMission:getFarmId() == farmId) |
842 | |
843 | PlaceableTrainSystemRentEvent.sendEvent(self, true, farmId, position, noEventSend) |
844 | end |
returnRailroad
DescriptionDefinitionreturnRailroad()Code
848 | function PlaceableTrainSystem:returnRailroad(noEventSend) |
849 | local spec = self.spec_trainSystem |
850 | spec.isRented = false |
851 | |
852 | if self.isServer then |
853 | if spec.currentPrice > 0 then |
854 | g_currentMission:addMoney(-spec.currentPrice, spec.rentFarmId, MoneyType.LEASING_COSTS, true) |
855 | g_currentMission:showMoneyChange(MoneyType.LEASING_COSTS, nil, false, spec.rentFarmId) |
856 | spec.currentPrice = 0 |
857 | end |
858 | |
859 | spec.rootLocomotive:startAutomatedTrainTravel() |
860 | end |
861 | |
862 | spec.rentFarmId = FarmManager.SPECTATOR_FARM_ID |
863 | |
864 | for _, railroadVehicle in ipairs(spec.railroadVehicles) do |
865 | railroadVehicle:setOwnerFarmId(spec.rentFarmId, true) |
866 | end |
867 | |
868 | self:setIsTrainTabbable(false) |
869 | |
870 | PlaceableTrainSystemRentEvent.sendEvent(self, false, nil, nil, noEventSend) |
871 | end |
saveToXMLFile
DescriptionDefinitionsaveToXMLFile()Code
479 | function PlaceableTrainSystem:saveToXMLFile(xmlFile, key, usedModNames) |
480 | local spec = self.spec_trainSystem |
481 | |
482 | xmlFile:setValue(key.."#splineTime", SplineUtil.getValidSplineTime(spec.splineTime)) |
483 | |
484 | for k, railroadVehicle in ipairs(spec.railroadVehicles) do |
485 | local railroadKey = string.format("%s.railroadVehicle(%d)", key, k-1) |
486 | xmlFile:setValue(railroadKey.."#vehicleId", railroadVehicle.currentSavegameId or 0) |
487 | end |
488 | |
489 | for k, railroadObject in ipairs(spec.railroadObjects) do |
490 | local railroadKey = string.format("%s.railroadObjects(%d)", key, k-1) |
491 | if railroadObject.saveToXMLFile ~= nil then |
492 | xmlFile:setValue(railroadKey.."#index", k) |
493 | railroadObject.saveToXMLFile(xmlFile, railroadKey, usedModNames) |
494 | end |
495 | end |
496 | |
497 | xmlFile:setValue(key.."#isRented", spec.isRented) |
498 | xmlFile:setValue(key.."#rentFarmId", spec.rentFarmId) |
499 | xmlFile:setValue(key.."#currentPrice", spec.currentPrice) |
500 | end |
sellGoods
DescriptionDefinitionsellGoods()Code
1058 | function PlaceableTrainSystem:sellGoods() |
1059 | local spec = self.spec_trainSystem |
1060 | if spec.sellingStation ~= nil and spec.rentFarmId ~= 0 then |
1061 | local soldDelta = 0 |
1062 | for _,railroadVehicle in ipairs(spec.railroadVehicles) do |
1063 | if railroadVehicle.getFillUnits ~= nil then |
1064 | local fillUnits = railroadVehicle:getFillUnits() |
1065 | for fillUnitIndex, fillUnit in ipairs(fillUnits) do |
1066 | local delta = spec.sellingStation:addFillLevelFromTool(spec.rentFarmId, fillUnit.fillLevel, fillUnit.fillType, nil, ToolType.UNDEFINED) |
1067 | railroadVehicle:addFillUnitFillLevel(railroadVehicle:getOwnerFarmId(), fillUnitIndex, -delta, fillUnit.fillType, ToolType.UNDEFINED, nil) |
1068 | soldDelta = soldDelta + delta |
1069 | end |
1070 | end |
1071 | end |
1072 | |
1073 | -- if we've sold something we return the train |
1074 | if soldDelta > 0 then |
1075 | if spec.isRented then |
1076 | self:returnRailroad() |
1077 | end |
1078 | end |
1079 | end |
1080 | end |
setIsTrainTabbable
DescriptionDefinitionsetIsTrainTabbable()Code
707 | function PlaceableTrainSystem:setIsTrainTabbable(isTabbable) |
708 | local spec = self.spec_trainSystem |
709 | |
710 | isTabbable = isTabbable and g_gameSettings:getValue("isTrainTabbable") |
711 | |
712 | if spec.hasLimitedRange then |
713 | isTabbable = isTabbable and spec.lastIsInDriveableRange |
714 | end |
715 | |
716 | for _,railroadVehicle in ipairs(spec.railroadVehicles) do |
717 | if railroadVehicle.setIsTabbable ~= nil then |
718 | railroadVehicle:setIsTabbable(isTabbable) |
719 | end |
720 | end |
721 | end |
setSplineTime
DescriptionDefinitionsetSplineTime()Code
737 | function PlaceableTrainSystem:setSplineTime(startTime, endTime) |
738 | local spec = self.spec_trainSystem |
739 | if startTime ~= spec.splineTime then |
740 | if spec.hasLimitedRange then |
741 | self:updateDriveableState(startTime) |
742 | end |
743 | |
744 | local t1 = SplineUtil.getValidSplineTime(startTime) |
745 | for _,railroadVehicle in ipairs(spec.railroadVehicles) do |
746 | t1 = railroadVehicle:alignToSplineTime(spec.spline, spec.splineYOffset, t1) |
747 | end |
748 | for _,listener in ipairs(spec.splinePositionUpdateListener) do |
749 | listener:onSplinePositionTimeUpdate(startTime, endTime) |
750 | end |
751 | spec.splineTime = startTime |
752 | spec.splineEndTime = endTime |
753 | |
754 | if self.isServer then |
755 | local threshold = 0.02 / spec.splineLength -- 2 cm threshold |
756 | if math.abs(spec.splineTime-spec.splineTimeSent) > threshold then |
757 | spec.splineTimeSent = spec.splineTime |
758 | self:raiseDirtyFlags(spec.dirtyFlag) |
759 | end |
760 | end |
761 | end |
762 | end |
toggleRent
DescriptionDefinitiontoggleRent()Code
815 | function PlaceableTrainSystem:toggleRent(farmId, position) |
816 | local spec = self.spec_trainSystem |
817 | |
818 | if spec.isRented then |
819 | if spec.rentFarmId == farmId then |
820 | self:returnRailroad() |
821 | end |
822 | else |
823 | self:rentRailroad(farmId, position, false) |
824 | end |
825 | end |
updateDriveableState
DescriptionDefinitionupdateDriveableState()Code
959 | function PlaceableTrainSystem:updateDriveableState(newSplineTime) |
960 | local spec = self.spec_trainSystem |
961 | |
962 | local isInDriveableRange = (newSplineTime % 1) >= spec.splineDriveRange[1] and (newSplineTime % 1) <= spec.splineDriveRange[2] |
963 | if isInDriveableRange ~= spec.lastIsInDriveableRange then |
964 | spec.lastIsInDriveableRange = isInDriveableRange |
965 | if not isInDriveableRange then |
966 | for _,railroadVehicle in ipairs(spec.railroadVehicles) do |
967 | if self.isClient then |
968 | if railroadVehicle.getIsEntered ~= nil and railroadVehicle:getIsEntered() then |
969 | g_currentMission:onLeaveVehicle() |
970 | |
971 | -- show a bit delayed so the player is positionated correctly |
972 | spec.showDialogDelay = 100 |
973 | spec.showDialog = 1 |
974 | if self:gsIsTrainFilled() then |
975 | spec.showDialog = 2 |
976 | end |
977 | end |
978 | end |
979 | |
980 | if self.isServer then |
981 | local locomotiveSpec = railroadVehicle.spec_locomotive |
982 | if locomotiveSpec ~= nil then |
983 | if locomotiveSpec.state ~= Locomotive.STATE_AUTOMATIC_TRAVEL_ACTIVE |
984 | and locomotiveSpec.state ~= Locomotive.STATE_REQUESTED_POSITION |
985 | and locomotiveSpec.state ~= Locomotive.STATE_REQUESTED_POSITION_BRAKING then |
986 | railroadVehicle:setLocomotiveState(Locomotive.STATE_AUTOMATIC_TRAVEL_ACTIVE) |
987 | |
988 | -- return rental if train is empty so user will not pay for the drive outside of the map |
989 | if not self:gsIsTrainFilled() then |
990 | if spec.isRented then |
991 | self:returnRailroad() |
992 | end |
993 | end |
994 | |
995 | if spec.splineTime < newSplineTime then |
996 | locomotiveSpec.sellingDirection = 1 |
997 | else |
998 | locomotiveSpec.sellingDirection = -1 |
999 | end |
1000 | end |
1001 | end |
1002 | end |
1003 | end |
1004 | else |
1005 | if self.isServer then |
1006 | for _,railroadVehicle in ipairs(spec.railroadVehicles) do |
1007 | local locomotiveSpec = railroadVehicle.spec_locomotive |
1008 | if locomotiveSpec ~= nil then |
1009 | if not railroadVehicle:getIsReadyForAutomatedTrainTravel() then |
1010 | if locomotiveSpec.state == Locomotive.STATE_AUTOMATIC_TRAVEL_ACTIVE then |
1011 | railroadVehicle:setLocomotiveState(Locomotive.STATE_MANUAL_TRAVEL_INACTIVE) |
1012 | locomotiveSpec.sellingDirection = 1 |
1013 | end |
1014 | else |
1015 | if locomotiveSpec.sellingDirection ~= nil and locomotiveSpec.sellingDirection < 0 then |
1016 | locomotiveSpec.sellingDirection = 1 |
1017 | |
1018 | railroadVehicle:setLocomotiveState(Locomotive.STATE_MANUAL_TRAVEL_INACTIVE) |
1019 | end |
1020 | end |
1021 | end |
1022 | end |
1023 | end |
1024 | end |
1025 | |
1026 | self:setIsTrainTabbable(spec.isRented and g_currentMission:getFarmId() == spec.rentFarmId) |
1027 | end |
1028 | end |
updateTrainLength
DescriptionDefinitionupdateTrainLength()Code
804 | function PlaceableTrainSystem:updateTrainLength(splinePosition) |
805 | local spec = self.spec_trainSystem |
806 | for _,railroadVehicle in ipairs(spec.railroadVehicles) do |
807 | spec.trainLength = spec.trainLength + railroadVehicle:getFrontToBackDistance() |
808 | end |
809 | spec.trainLengthSplineTime = spec.trainLength / spec.splineLength |
810 | self:updateTrainPositionByLocomotiveSplinePosition(splinePosition) |
811 | end |
updateTrainPositionByLocomotiveSpeed
DescriptionDefinitionupdateTrainPositionByLocomotiveSpeed()Code
784 | function PlaceableTrainSystem:updateTrainPositionByLocomotiveSpeed(dt, speed) |
785 | local spec = self.spec_trainSystem |
786 | local distance = speed * (dt / 1000) |
787 | local increment = distance / spec.splineLength |
788 | local splineTime = self:getSplineTime() + increment |
789 | |
790 | self:setSplineTime(splineTime, splineTime-spec.trainLengthSplineTime) |
791 | end |
updateTrainPositionByLocomotiveSplinePosition
DescriptionDefinitionupdateTrainPositionByLocomotiveSplinePosition()Code
795 | function PlaceableTrainSystem:updateTrainPositionByLocomotiveSplinePosition(splinePosition) |
796 | local spec = self.spec_trainSystem |
797 | local splineTime = splinePosition |
798 | |
799 | self:setSplineTime(splineTime, splineTime-spec.trainLengthSplineTime) |
800 | end |