-
Notifications
You must be signed in to change notification settings - Fork 0
/
ExtendedLoadingStation.lua
338 lines (254 loc) · 11.8 KB
/
ExtendedLoadingStation.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
--[[
Copyright (C) GtX (Andy), 2019
Author: GtX | Andy
Date: 21.09.2019
Revision: FS22-01
Contact:
https://forum.giants-software.com
https://github.com/GtX-Andy
Important:
Free for use in mods (FS22 Only) - no permission needed.
No modifications may be made to this script, including conversion to other game versions without written permission from GtX | Andy
Copying or removing any part of this code for external use without written permission from GtX | Andy is prohibited.
Frei verwendbar (Nur LS22) - keine erlaubnis nötig
Ohne schriftliche Genehmigung von GtX | Andy dürfen keine Änderungen an diesem Skript vorgenommen werden, einschließlich der Konvertierung in andere Spielversionen
Das Kopieren oder Entfernen irgendeines Teils dieses Codes zur externen Verwendung ohne schriftliche Genehmigung von GtX | Andy ist verboten.
]]
ExtendedLoadingStation = {}
local ExtendedLoadingStation_mt = Class(ExtendedLoadingStation, LoadingStation)
InitObjectClass(ExtendedLoadingStation, "ExtendedLoadingStation")
function ExtendedLoadingStation.registerXMLPaths(schema, basePath)
LoadingStation.registerXMLPaths(schema, basePath)
schema:register(XMLValueType.NODE_INDEX, basePath .. ".loadTrigger(?).playerTrigger#node", "Player trigger node for external operation")
schema:register(XMLValueType.BOOL, basePath .. ".loadTrigger(?).playerTrigger#externalActivation", "Start / Stop filling only possible by player in trigger")
ObjectChangeUtil.registerObjectChangeXMLPaths(schema, basePath .. ".loadTrigger(?)")
end
function ExtendedLoadingStation.new(isServer, isClient, customMt)
local self = LoadingStation.new(isServer, isClient, customMt or ExtendedLoadingStation_mt)
self.useOwnerForAccess = false
self.aiSupportedFillTypes = {}
self.supportedFillTypes = {}
self.basicFillTypes = {}
self.hasStoragePerFarm = false
self.owningPlaceable = nil
self.rootNodeName = ""
self.stationName = nil
self.supportsExtension = false
self.storageRadius = 50
return self
end
function ExtendedLoadingStation:load(components, xmlFile, key, customEnvironment, i3dMappings, rootNode)
rootNode = xmlFile:getValue(key .. "#node", rootNode, components, i3dMappings)
if rootNode == nil then
Logging.xmlError(xmlFile, "Missing node at '%s'", key)
return false
end
local stationName = xmlFile:getValue(key .. "#stationName")
if stationName ~= nil then
self.stationName = g_i18n:convertText(stationName, customEnvironment)
end
self.rootNode = rootNode
self.rootNodeName = getName(rootNode)
self.supportsExtension = xmlFile:getValue(key .. "#supportsExtension", self.supportsExtension)
self.storageRadius = xmlFile:getValue(key .. "#storageRadius", self.storageRadius)
local names = xmlFile:getValue(key .. "#fillTypes")
if names ~= nil then
local fillTypes = g_fillTypeManager:getFillTypesByNames(names, "Warning: [ExtendedLoadingStation] Failed to load invalid fillType '%s'.")
for _, fillType in pairs(fillTypes) do
self.basicFillTypes[fillType] = true
end
end
names = xmlFile:getValue(key .. "#fillTypeCategories")
if names ~= nil then
local fillTypes = g_fillTypeManager:getFillTypesByCategoryNames(names, "Warning: [ExtendedLoadingStation] Failed to load invalid fillType category '%s'.")
for _, fillType in pairs(fillTypes) do
self.basicFillTypes[fillType] = true
end
end
xmlFile:iterate(key .. ".loadTrigger", function (_, loadTriggerKey)
local loadTrigger = ExtendedLoadTrigger.new(self.isServer, self.isClient)
if loadTrigger:load(components, xmlFile, loadTriggerKey, i3dMappings, rootNode) then
loadTrigger:setSource(self)
loadTrigger:register(true)
table.insert(self.loadTriggers, loadTrigger)
else
loadTrigger:delete()
end
end)
self:updateSupportedFillTypes()
return true
end
function ExtendedLoadingStation:hasFarmAccessToStorage(farmId, storage)
-- Allow storage checks to be ignored instead check the owner farmId
if self.useOwnerForAccess and self.owningPlaceable then
return farmId == self.owningPlaceable:getOwnerFarmId()
end
return ExtendedLoadingStation:superClass().hasFarmAccessToStorage(self, farmId, storage)
end
-- Can be used separately if 'ExtendedLoadingStation' is not required, 'registerXMLPaths' is included for this reason
ExtendedLoadTrigger = {}
ExtendedLoadTrigger.MOD_DIRECTORY = g_currentModDirectory
local ExtendedLoadTrigger_mt = Class(ExtendedLoadTrigger, LoadTrigger)
InitObjectClass(ExtendedLoadTrigger, "ExtendedLoadTrigger")
function ExtendedLoadTrigger.registerXMLPaths(schema, basePath)
LoadTrigger.registerXMLPaths(schema, basePath)
schema:register(XMLValueType.NODE_INDEX, basePath .. ".playerTrigger#node", "Player trigger node for external operation")
ObjectChangeUtil.registerObjectChangeXMLPaths(schema, basePath)
end
function ExtendedLoadTrigger.new(isServer, isClient, customMt)
local self = LoadTrigger.new(isServer, isClient, customMt or ExtendedLoadTrigger_mt)
self.playerCanInteract = false
self.externalActivation = false
self.interactionTrigger = nil
return self
end
function ExtendedLoadTrigger:load(components, xmlFile, xmlNode, i3dMappings, rootNode)
if not ExtendedLoadTrigger:superClass().load(self, components, xmlFile, xmlNode, i3dMappings, rootNode) then
return false
end
self.interactionTrigger = xmlFile:getValue(xmlNode .. ".playerTrigger#node", nil, components, i3dMappings)
if self.interactionTrigger ~= nil then
if not CollisionFlag.getHasFlagSet(self.interactionTrigger, CollisionFlag.TRIGGER_PLAYER) then
Logging.xmlWarning(xmlFile, "Player trigger '%s.playerTrigger' does not have Bit '%d' (CollisionFlag.TRIGGER_PLAYER) set!", key, CollisionFlag.getBit(CollisionFlag.TRIGGER_PLAYER))
end
self.externalActivation = xmlFile:getValue(xmlNode .. ".playerTrigger#externalActivation", false)
addTrigger(self.interactionTrigger, "interactionTriggerCallback", self)
end
if self.isClient then
self.objectChanges = {}
self.i3dMappings = i3dMappings
ObjectChangeUtil.loadObjectChangeFromXML(xmlFile, xmlNode, self.objectChanges, components, self)
ObjectChangeUtil.setObjectChanges(self.objectChanges, false)
if #self.objectChanges == 0 then
self.objectChanges = nil
end
self.i3dMappings = nil -- Not needed anymore, only used for 'loadObjectChangeFromXML'
end
return true
end
function ExtendedLoadTrigger:delete()
if self.interactionTrigger ~= nil then
removeTrigger(self.interactionTrigger)
self.playerCanInteract = false
self.interactionTrigger = nil
end
ExtendedLoadTrigger:superClass().delete(self)
end
function ExtendedLoadTrigger:update(dt)
ExtendedLoadTrigger:superClass().update(self, dt)
if self.interactionTrigger ~= nil and self.playerCanInteract then
if self.source ~= nil then
if g_currentMission.controlPlayer and g_currentMission.accessHandler:canFarmAccess(g_currentMission:getFarmId(), self.source) then
self:raiseActive()
else
self.playerCanInteract = false
end
else
self.playerCanInteract = false
end
end
end
function ExtendedLoadTrigger:toggleLoading()
if not self.isLoading then
local fillLevels = self.source:getAllFillLevels(g_currentMission:getFarmId())
local fillableObject = self.validFillableObject
local fillUnitIndex = self.validFillableFillUnitIndex
local firstFillType = nil
local validFillLevels = {}
local numFillTypes = 0
for fillTypeIndex, fillLevel in pairs(fillLevels) do
if self.fillTypes == nil or self.fillTypes[fillTypeIndex] then
if fillableObject:getFillUnitAllowsFillType(fillUnitIndex, fillTypeIndex) then
validFillLevels[fillTypeIndex] = fillLevel
if firstFillType == nil then
firstFillType = fillTypeIndex
end
numFillTypes = numFillTypes + 1
end
end
end
if not self.autoStart and numFillTypes > 1 then
local startAllowed = true
local controlledVehicle = g_currentMission.controlledVehicle
if controlledVehicle ~= nil and controlledVehicle.getIsActiveForInput ~= nil then
startAllowed = controlledVehicle:getIsActiveForInput(true)
end
if startAllowed then
local text = string.format("%s", self.source:getName())
g_gui:showSiloDialog({
hasInfiniteCapacity = self.hasInfiniteCapacity,
callback = self.onFillTypeSelection,
fillLevels = validFillLevels,
target = self,
title = text
})
end
else
self:onFillTypeSelection(firstFillType)
end
else
self:setIsLoading(false)
end
end
function ExtendedLoadTrigger:startLoading(fillType, fillableObject, fillUnitIndex)
if not self.isLoading then
self:raiseActive()
self.isLoading = true
self.selectedFillType = fillType
self.currentFillableObject = fillableObject
self.fillUnitIndex = fillUnitIndex
self.activatable:setText(self.stopFillText)
if self.isClient then
ObjectChangeUtil.setObjectChanges(self.objectChanges, true)
g_effectManager:setFillType(self.effects, self.selectedFillType)
g_effectManager:startEffects(self.effects)
g_soundManager:playSample(self.samples.load)
if self.scroller ~= nil then
setShaderParameter(self.scroller, self.scrollerShaderParameterName, self.scrollerSpeedX, self.scrollerSpeedY, 0, 0, false)
end
end
end
end
function ExtendedLoadTrigger:stopLoading()
if self.isLoading then
self:raiseActive()
self.isLoading = false
self.selectedFillType = FillType.UNKNOWN
self.activatable:setText(self.startFillText)
if self.currentFillableObject.aiStoppedLoadingFromTrigger ~= nil then
self.currentFillableObject:aiStoppedLoadingFromTrigger()
end
for _, fillableObject in pairs(self.fillableObjects) do
fillableObject.lastWasFilled = fillableObject.object == self.validFillableObject
end
if self.isClient then
ObjectChangeUtil.setObjectChanges(self.objectChanges, false)
g_effectManager:stopEffects(self.effects)
g_soundManager:stopSample(self.samples.load)
if self.scroller ~= nil then
setShaderParameter(self.scroller, self.scrollerShaderParameterName, 0, 0, 0, 0, false)
end
end
end
end
function ExtendedLoadTrigger:getAllowsActivation(fillableObject)
if self.interactionTrigger ~= nil then
if self.playerCanInteract then
if self.source ~= nil and g_currentMission.accessHandler:canFarmAccess(g_currentMission:getFarmId(), self.source) then
return true
end
elseif self.externalActivation then
return false
end
end
return ExtendedLoadTrigger:superClass().getAllowsActivation(self, fillableObject)
end
function ExtendedLoadTrigger:interactionTriggerCallback(triggerId, otherId, onEnter, onLeave, onStay, otherShapeId)
if (onEnter or onLeave) and g_currentMission.player and g_currentMission.player.rootNode == otherId then
if onEnter then
self.playerCanInteract = self.source ~= nil
else
self.playerCanInteract = false
end
end
end