Script v1.4.4.0
- Handtools
- Events
- Objects
- Placeables
- Triggers
- BaleDestroyerTrigger
- BasketTrigger
- ConveyorBeltTipTrigger
- FillTrigger
- GasStationTrigger
- LiquidManureFillTrigger
- LoanTrigger
- PickupObjectsSellTrigger
- ReceivingTipTrigger
- ShopTrigger
- SiloTrigger
- TipTrigger
- WaterTrailerFillTrigger
- WeighStation
- WoodSellTrigger
- Utils
- Vehicles
- Specializations
Engine v7.0.0.2
- General
- Entity
- Node
- Scenegraph
- Lighting
- Camera
- Shape
- Particle System
- Physics
- Spline
- Animation
- Overlays
- Sound
- Input
- XML
- Network
- Callbacks
- Text Rendering
- Terrain Detail
- Tire Track
- Editor
- Rendering
- String
- Math
- I3D
- Fillplanes
Foundation Reference
TipTrigger
DescriptionClass for tip triggerFunctions
- onCreate
- new
- load
- delete
- addAcceptedFillType
- initPricingDynamics
- executePriceDrop
- doPriceDrop
- updatePrices
- getEffectiveFillTypePrice
- setPriceMultiplier
- setIsInGreatDemand
- getPriceMultiplier
- getTotalReceived
- getTotalPaid
- getCurrentPricingTrend
- readStream
- writeStream
- readUpdateStream
- writeUpdateStream
- loadFromAttributesAndNodes
- getSaveAttributesAndNodes
- update
- updateTick
- getAllowFillTypeFromTool
- addFillLevelFromTool
- sellFillType
- getIncomeNameForFillType
- getTipInfoForTrailer
- getTipDistanceFromTrailer
- getNotAllowedText
- addTipTriggerTarget
- removeTipTriggerTarget
- updateFillTypes
- addUpdateEventListener
- removeUpdateEventListener
- triggerCallback
onCreate
DescriptionOn create tip triggerDefinition
onCreate(integer id)Arguments
integer | id | trigger node id |
28 | function TipTrigger:onCreate(id) |
29 | local trigger = TipTrigger:new(g_server ~= nil, g_client ~= nil) |
30 | if trigger:load(id) then |
31 | trigger:register(true) |
32 | g_currentMission:addOnCreateLoadedObject(trigger) |
33 | g_currentMission:addOnCreateLoadedObjectToSave(trigger); |
34 | else |
35 | trigger:delete() |
36 | end |
37 | end |
new
DescriptionCreating tip trigger objectDefinition
new(boolean isServer, boolean isClient, table customMt)Arguments
boolean | isServer | is server |
boolean | isClient | is client |
table | customMt | custom metatable (optional) |
table | instance | Instance of object |
45 | function TipTrigger:new(isServer, isClient, customMt) |
46 | if customMt == nil then |
47 | customMt = TipTrigger_mt |
48 | end |
49 | local self = Object:new(isServer, isClient, customMt) |
50 | self.triggerId = 0 |
51 | self.rootNode = 0 |
52 | self.objectsInTrigger = {}; |
53 | self.incomeName = "harvestIncome"; |
54 | self.incomeNameWool = "soldWool"; |
55 | |
56 | g_currentMission:addTipTrigger(self) |
57 | |
58 | self.tipTriggerDirtyFlag = self:getNextDirtyFlag() |
59 | |
60 | self.lastMoneyChange = -1 |
61 | |
62 | return self |
63 | end |
load
DescriptionLoad tip triggerDefinition
load(integer id)Arguments
integer | id | id of trigger node |
boolean | success | success |
69 | function TipTrigger:load(id) |
70 | |
71 | self.rootNode = id |
72 | self.stationName = Utils.getNoNil(getUserAttribute(id, "stationName"), "Station") |
73 | self.triggerId = Utils.indexToObject(id, getUserAttribute(id, "triggerIndex")) |
74 | if self.triggerId == nil then |
75 | self.triggerId = id |
76 | end |
77 | addTrigger(self.triggerId, "triggerCallback", self) |
78 | |
79 | self.baleTriggerId = Utils.indexToObject(id, getUserAttribute(id, "baleTriggerIndex")) |
80 | if self.baleTriggerId ~= nil then |
81 | addTrigger(self.baleTriggerId, "baleTriggerCallback", self) |
82 | end |
83 | |
84 | local shovelTargetNode = Utils.indexToObject(id, getUserAttribute(id, "shovelTargetIndex")) |
85 | if shovelTargetNode ~= nil then |
86 | self.shovelTarget = ShovelTarget:new(self) |
87 | if not self.shovelTarget:load(shovelTargetNode) then |
88 | self.shovelTarget:delete() |
89 | self.shovelTarget = nil |
90 | end |
91 | end |
92 | |
93 | local movingIndex = getUserAttribute(id, "movingIndex"); |
94 | if movingIndex ~= nil then |
95 | local movingRootNode = id; |
96 | if self.triggerId == id then |
97 | movingRootNode = getParent(id); |
98 | end |
99 | self.movingId = Utils.indexToObject(movingRootNode, movingIndex); |
100 | if self.movingId ~= nil then |
101 | self.moveMinY = Utils.getNoNil(getUserAttribute(id, "moveMinY"), 0); |
102 | self.moveMaxY = Utils.getNoNil(getUserAttribute(id, "moveMaxY"), 0); |
103 | self.moveScale = Utils.getNoNil(getUserAttribute(id, "moveScale"), 0.001)*0.01; |
104 | self.moveBackScale = (self.moveMaxY-self.moveMinY)/Utils.getNoNil(getUserAttribute(id, "moveBackTime"), 10000); |
105 | end; |
106 | end; |
107 | |
108 | self.isSellingPoint = Utils.getNoNil(getUserAttribute(id, "isSellingPoint"), false) |
109 | self.appearsOnPDA = Utils.getNoNil(getUserAttribute(id, "appearsOnPDA"), false) |
110 | self.appearsOnStats = Utils.getNoNil(getUserAttribute(id, "appearsOnStats"), self.appearsOnPDA) |
111 | self.suppressWarnings = Utils.getNoNil(getUserAttribute(id, "suppressWarnings"), false) |
112 | self.storageRadius = Utils.getNoNil(getUserAttribute(id, "storageRadius"), 50) |
113 | self.isAreaTrigger = Utils.getNoNil(getUserAttribute(id, "isAreaTrigger"), false) |
114 | self.isTrainOnly = Utils.getNoNil(getUserAttribute(id, "isTrainOnly"), false) |
115 | self.supportsExtension = Utils.getNoNil(getUserAttribute(id, "supportsExtension"), false) |
116 | self.hasDynamic = Utils.getNoNil(getUserAttribute(id, "hasDynamic"), true) |
117 | |
118 | self.triggerTipWidth = Utils.getNoNil(getUserAttribute(id, "triggerTipWidth"), math.huge) |
119 | self.priceDropPerLiter = (1-EconomyManager.PRICE_DROP_MIN_PERCENT) / Utils.getNoNil(getUserAttribute(id, "litersForFullPriceDrop"), 100000) -- 40% with 100000 liter |
120 | self.priceRecoverPerSecond = (1-EconomyManager.PRICE_DROP_MIN_PERCENT) / (Utils.getNoNil(getUserAttribute(id, "fullPriceRecoverHours"), (3.0*24)) * 60*60) -- full recovery (40% increase) in 3 days |
121 | |
122 | self.supportsGreatDemand = false |
123 | self.isGreatDemandActive = false |
124 | self.greatDemandFillType = FillUtil.FILLTYPE_UNKNOWN |
125 | self.priceDropTimer = 0 |
126 | self.levelThreshold = 0 |
127 | self.numFillTypesForSelling = 0 |
128 | self.pricingDynamics = {} |
129 | self.handleFilling = true |
130 | |
131 | if self.acceptedFillTypes == nil then |
132 | if getUserAttribute(id, "fruitTypes") ~= nil then |
133 | print("Warning: Attribute 'fruitTypes' is not supported anymore. Please use 'fillTypes' instead") |
134 | end |
135 | |
136 | self.acceptedFillTypes = {} |
137 | self.fillTypeSupportsGreatDemand = {} |
138 | self.priceDropDisabled = {} |
139 | self.originalFillTypePricesUnscaled = {} |
140 | self.originalFillTypePrices = {} |
141 | self.fillTypePrices = {} |
142 | self.fillTypePriceInfo = {} |
143 | self.fillTypePriceRandomDelta = {} |
144 | self.priceMultipliers = {} |
145 | self.totalReceived = {} |
146 | self.totalPaid = {} |
147 | self.pendingPriceDrop = {} |
148 | self.prevFillLevel = {} |
149 | self.prevTotalReceived = {} |
150 | self.prevTotalPaid = {} |
151 | self.allowedToolTypes = {} |
152 | end |
153 | |
154 | |
155 | local xmlFilename = getUserAttribute(id, "xmlFile"); |
156 | local useMapConfigXml = Utils.getNoNil(getUserAttribute(id, "useMapConfigXml"), false) |
157 | |
158 | if xmlFilename == nil and useMapConfigXml then |
159 | xmlFilename = g_currentMission.missionInfo.mapXmlFilename |
160 | end |
161 | |
162 | if xmlFilename ~= nil then |
163 | xmlFilename = Utils.getFilename(xmlFilename, g_currentMission.loadingMapBaseDirectory); |
164 | local xmlFile = loadXMLFile("TipTrigger", xmlFilename); |
165 | if xmlFile ~= 0 then |
166 | local index = getUserAttribute(id, "index"); |
167 | if index ~= nil then |
168 | local key = nil |
169 | local i = 0 |
170 | while true do |
171 | local triggerKey = string.format("map.tipTriggers.tipTrigger(%d)", i) |
172 | if not hasXMLProperty(xmlFile, triggerKey) then |
173 | break |
174 | end |
175 | |
176 | local configIndex = getXMLString(xmlFile, triggerKey.."#index") |
177 | if configIndex == index then |
178 | key = triggerKey |
179 | break |
180 | end |
181 | i = i + 1 |
182 | end |
183 | |
184 | if key ~= nil then |
185 | self.stationName = Utils.getNoNil(getXMLString(xmlFile, key.."#stationName"), self.stationName) |
186 | self.isSellingPoint = Utils.getNoNil(getXMLBool(xmlFile, key.."#isSellingPoint"), self.isSellingPoint) |
187 | self.appearsOnPDA = Utils.getNoNil(getXMLBool(xmlFile, key.."#appearsOnPDA"), self.appearsOnPDA) |
188 | self.appearsOnStats = Utils.getNoNil(getXMLBool(xmlFile, key.."#appearsOnStats"), self.appearsOnPDA or self.appearsOnStats) |
189 | self.suppressWarnings = Utils.getNoNil(getXMLBool(xmlFile, key.."#suppressWarnings"), self.suppressWarnings) |
190 | self.storageRadius = Utils.getNoNil(getXMLFloat(xmlFile, key.."#storageRadius"), self.storageRadius) |
191 | self.triggerWidth = Utils.getNoNil(getXMLFloat(xmlFile, key.."#triggerWidth"), self.triggerWidth) |
192 | self.triggerTipWidth = Utils.getNoNil(getXMLFloat(xmlFile, key.."#triggerTipWidth"), self.triggerTipWidth) |
193 | self.isAreaTrigger = Utils.getNoNil(getXMLBool(xmlFile, key.."#isAreaTrigger"), self.isAreaTrigger) |
194 | self.isTrainOnly = Utils.getNoNil(getXMLBool(xmlFile, key.."#isTrainOnly"), self.isTrainOnly) |
195 | self.hasDynamic = Utils.getNoNil(getXMLBool(xmlFile, key.."#hasDynamic"), self.hasDynamic) |
196 | self.supportsExtension = Utils.getNoNil(getXMLBool(xmlFile, key.."#supportsExtension"), self.supportsExtension) |
197 | local litersForFullPriceDrop = getXMLInt(xmlFile, key.."#litersForFullPriceDrop") |
198 | if litersForFullPriceDrop ~= nil then |
199 | self.priceDropPerLiter = (1-EconomyManager.PRICE_DROP_MIN_PERCENT) / litersForFullPriceDrop |
200 | end |
201 | local fullPriceRecoverHours = getXMLFloat(xmlFile, key.."#fullPriceRecoverHours") |
202 | if fullPriceRecoverHours ~= nil then |
203 | self.priceRecoverPerSecond = (1-EconomyManager.PRICE_DROP_MIN_PERCENT) / (fullPriceRecoverHours * 60*60) |
204 | end |
205 | |
206 | local defaultPriceScale = 0 |
207 | if self.isSellingPoint then |
208 | defaultPriceScale = 1 |
209 | end |
210 | self.saveId = Utils.getNoNil(getXMLString(xmlFile, key.."#saveId"), "TipTrigger_"..index); |
211 | |
212 | local i = 0 |
213 | while true do |
214 | local fillTypeKey = string.format(key..".fillType(%d)", i) |
215 | if not hasXMLProperty(xmlFile, fillTypeKey) then |
216 | break |
217 | end |
218 | |
219 | local fillTypeStr = getXMLString(xmlFile, fillTypeKey.."#name") |
220 | local fillType = FillUtil.fillTypeNameToInt[fillTypeStr] |
221 | if fillType ~= nil then |
222 | local priceScale = Utils.getNoNil(getXMLFloat(xmlFile, fillTypeKey.."#priceScale"), defaultPriceScale) |
223 | local price = FillUtil.fillTypeIndexToDesc[fillType].pricePerLiter * priceScale; |
224 | local supportsGreatDemand = Utils.getNoNil(getXMLBool(xmlFile, fillTypeKey.."#supportsGreatDemand"), false) |
225 | local disablePriceDrop = Utils.getNoNil(getXMLBool(xmlFile, fillTypeKey.."#disablePriceDrop"), false) |
226 | |
227 | |
228 | local allowedToolTypes = {} |
229 | if Utils.getNoNil(getXMLBool(xmlFile, fillTypeKey.."#allowTrailers"), true) then |
230 | table.insert(allowedToolTypes, TipTrigger.TOOL_TYPE_TRAILER); |
231 | end |
232 | if Utils.getNoNil(getXMLBool(xmlFile, fillTypeKey.."#allowShovels"), true) then |
233 | table.insert(allowedToolTypes, TipTrigger.TOOL_TYPE_SHOVEL); |
234 | end |
235 | if Utils.getNoNil(getXMLBool(xmlFile, fillTypeKey.."#allowPipes"), true) then |
236 | table.insert(allowedToolTypes, TipTrigger.TOOL_TYPE_PIPE); |
237 | end |
238 | if Utils.getNoNil(getXMLBool(xmlFile, fillTypeKey.."#allowPallets"), true) then |
239 | table.insert(allowedToolTypes, TipTrigger.TOOL_TYPE_PALLET); |
240 | end |
241 | self:addAcceptedFillType(fillType, price, supportsGreatDemand, disablePriceDrop, allowedToolTypes) |
242 | end |
243 | |
244 | i = i + 1 |
245 | end |
246 | end |
247 | |
248 | delete(xmlFile) |
249 | |
250 | if key == nil then |
251 | print("Error: '"..self.stationName.."' not defined in config file '"..xmlFilename.."'") |
252 | return false |
253 | end |
254 | else |
255 | print("Error: no mapping index defined for '"..self.stationName.."' in config file '"..xmlFilename.."'") |
256 | return false |
257 | end |
258 | else |
259 | print("Error: Could not load tiptrigger config file '"..tostring(xmlFilename).."'") |
260 | return false |
261 | end |
262 | else |
263 | local fillTypes = Utils.splitString(" ", getUserAttribute(id, "fillTypes")) |
264 | local priceScales = Utils.splitString(" ", getUserAttribute(id, "priceScales")) |
265 | local supportsGreatDemands = Utils.splitString(" ", getUserAttribute(id, "supportsGreatDemand")) |
266 | local disablePriceDrops = Utils.splitString(" ", getUserAttribute(id, "disablePriceDrop")) |
267 | |
268 | for k, fillTypeStr in pairs(fillTypes) do |
269 | local fillType = FillUtil.fillTypeNameToInt[fillTypeStr] |
270 | if fillType ~= nil then |
271 | local priceScale = tonumber(Utils.getNoNil(priceScales[k], "0")) |
272 | local price = FillUtil.fillTypeIndexToDesc[fillType].pricePerLiter * priceScale; |
273 | local supportsGreatDemand = Utils.getNoNil(supportsGreatDemands[k], "false") ~= "false" |
274 | local disablePriceDrop = Utils.getNoNil(disablePriceDrops[k], "false") == "true" |
275 | self:addAcceptedFillType(fillType, price, supportsGreatDemand, disablePriceDrop, {TipTrigger.TOOL_TYPE_TRAILER, TipTrigger.TOOL_TYPE_SHOVEL, TipTrigger.TOOL_TYPE_PIPE, TipTrigger.TOOL_TYPE_PALLET}) |
276 | end |
277 | end |
278 | |
279 | self.saveId = Utils.getNoNil(getUserAttribute(id, "saveId"), "TipTrigger_"..self.stationName); |
280 | end |
281 | |
282 | self:initPricingDynamics() |
283 | |
284 | if self.isAreaTrigger then |
285 | self.triggerStartId = getChildAt(id, 0) |
286 | self.triggerEndId = getChildAt(id, 1) |
287 | self.triggerWidth = Utils.getNoNil(getUserAttribute(id, "triggerWidth"), 3) |
288 | else |
289 | self.triggerStartId = self.triggerId |
290 | end |
291 | |
292 | if self.appearsOnPDA then |
293 | local mapPosition = id |
294 | local mapPositionIndex = getUserAttribute(id, "mapPositionIndex") |
295 | if mapPositionIndex ~= nil then |
296 | mapPosition = Utils.indexToObject(id, mapPositionIndex) |
297 | if mapPosition == nil then |
298 | mapPosition = id |
299 | end |
300 | end |
301 | local filenames = nil |
302 | local imageUVs = getNormalizedUVs({520, 520, 240, 240}) |
303 | local x, _, z = getWorldTranslation(mapPosition) |
304 | |
305 | local i18n = g_i18n; |
306 | if g_currentMission.missionInfo.customEnvironment ~= nil then |
307 | i18n = _G[g_currentMission.missionInfo.customEnvironment].g_i18n; |
308 | end |
309 | |
310 | local fullViewName = self.stationName |
311 | if i18n:hasText(fullViewName) then |
312 | fullViewName = i18n:getText(fullViewName) |
313 | end |
314 | |
315 | if self.isTrainOnly then |
316 | filenames = {"dataS/menu/mapHotspotTrain_1024.png", "dataS/menu/mapHotspotTrain_512.png", "dataS/menu/mapHotspotTrain_256.png", "dataS/menu/mapHotspotTrain_128.png", "dataS/menu/mapHotspotTrain_64.png"} |
317 | imageUVs = getNormalizedUVs({0, 0, 1024, 1024}, {1024, 1024}) |
318 | end |
319 | |
320 | self.mapHotspot = g_currentMission.ingameMap:createMapHotspot("tipTrigger", fullViewName, filenames, imageUVs, {0.9559, 0.5647, 0.0423, 1}, x, z, nil, nil, false, false, true, 0, nil, MapHotspot.CATEGORY_TRIGGER) |
321 | end |
322 | |
323 | self.tipTriggerTargets = nil |
324 | self.updateEventListeners = {} |
325 | self.isEnabled = true |
326 | |
327 | self.moneyChangeId = getMoneyTypeId() |
328 | |
329 | self.priceSyncTimerDuration = 30 * 1000 -- 30 seconds |
330 | self.priceSyncTimer = self.priceSyncTimerDuration |
331 | |
332 | return true |
333 | end |
delete
DescriptionDelete tip triggerDefinition
delete()Code
337 | function TipTrigger:delete() |
338 | if self.shovelTarget ~= nil then |
339 | self.shovelTarget:delete() |
340 | end |
341 | if self.mapHotspot ~= nil then |
342 | g_currentMission.ingameMap:deleteMapHotspot(self.mapHotspot) |
343 | end |
344 | for fillable,triggers in pairs(g_currentMission.trailerTipTriggers) do |
345 | if triggers ~= nil then |
346 | for i=1, table.getn(triggers) do |
347 | if triggers[i] == self then |
348 | table.remove(triggers, i) |
349 | if table.getn(triggers) == 0 then |
350 | g_currentMission.trailerTipTriggers[fillable] = nil |
351 | end |
352 | end |
353 | end |
354 | end |
355 | end |
356 | g_currentMission:removeTipTrigger(self) |
357 | if self.triggerId ~= 0 then |
358 | removeTrigger(self.triggerId) |
359 | self.triggerId = 0 |
360 | end |
361 | if self.baleTriggerId ~= nil and self.baleTriggerId ~= 0 then |
362 | removeTrigger(self.baleTriggerId) |
363 | self.baleTriggerId = 0 |
364 | end |
365 | if self.rootNode ~= 0 and self.rootNode ~= self.triggerId and entityExists(self.rootNode) then |
366 | delete(self.rootNode) |
367 | self.rootNode = 0 |
368 | end |
369 | |
370 | g_currentMission:removeOnCreateLoadedObjectToSave(self) |
371 | |
372 | TipTrigger:superClass().delete(self) |
373 | end |
addAcceptedFillType
DescriptionAdd fill type to tip triggerDefinition
addAcceptedFillType(integer fillType, float priceUnscaled, boolean supportsGreatDemand, boolean disablePriceDrop, table allowedToolTypes)Arguments
integer | fillType | fill type index |
float | priceUnscaled | price unscaled |
boolean | supportsGreatDemand | fill type supports great demands |
boolean | disablePriceDrop | disable price drop |
table | allowedToolTypes | allowed tool types |
382 | function TipTrigger:addAcceptedFillType(fillType, priceUnscaled, supportsGreatDemand, disablePriceDrop, allowedToolTypes) |
383 | if fillType ~= nil and self.acceptedFillTypes[fillType] == nil then |
384 | self.acceptedFillTypes[fillType] = true |
385 | self.fillTypeSupportsGreatDemand[fillType] = supportsGreatDemand |
386 | if supportsGreatDemand then |
387 | self.supportsGreatDemand = true |
388 | end |
389 | |
390 | local price = priceUnscaled * EconomyManager.getPriceMultiplier() |
391 | self.priceDropDisabled[fillType] = disablePriceDrop |
392 | self.originalFillTypePricesUnscaled[fillType] = priceUnscaled |
393 | self.originalFillTypePrices[fillType] = price |
394 | self.fillTypePrices[fillType] = price |
395 | self.fillTypePriceInfo[fillType] = 0 -- bitvector |
396 | self.fillTypePriceRandomDelta[fillType] = 0.0 |
397 | self.priceMultipliers[fillType] = 1.0 |
398 | self.totalReceived[fillType] = 0.0 |
399 | self.totalPaid[fillType] = 0.0 |
400 | self.pendingPriceDrop[fillType] = 0.0 |
401 | self.prevFillLevel[fillType] = 0.0 |
402 | self.prevTotalReceived[fillType] = 0.0 |
403 | self.prevTotalPaid[fillType] = 0.0 |
404 | self.allowedToolTypes[fillType] = {}; |
405 | for _,toolType in pairs(allowedToolTypes) do |
406 | self.allowedToolTypes[fillType][toolType] = true; |
407 | end |
408 | |
409 | self.numFillTypesForSelling = 0; |
410 | for fillType,_ in pairs(self.acceptedFillTypes) do |
411 | if self.originalFillTypePrices[fillType] > 0 then |
412 | self.numFillTypesForSelling = self.numFillTypesForSelling + 1 |
413 | end |
414 | end |
415 | end |
416 | end |
initPricingDynamics
DescriptionInitialize pricing dynamicsDefinition
initPricingDynamics()
executePriceDrop
DescriptionExecute price dropDefinition
executePriceDrop(float priceDrop, integer fillType)Arguments
float | priceDrop | price drop |
integer | fillType | fill type index |
459 | function TipTrigger:executePriceDrop(priceDrop, fillType) |
460 | local lowestPrice = self.originalFillTypePrices[fillType] * EconomyManager.PRICE_DROP_MIN_PERCENT |
461 | self.fillTypePrices[fillType] = math.max(self.fillTypePrices[fillType] - priceDrop, lowestPrice) |
462 | end |
doPriceDrop
DescriptionDo price drop after TipTrigger.PRICE_DROP_DELAYDefinition
doPriceDrop(float fillLevel, integer fillType)Arguments
float | fillLevel | fill level |
integer | fillType | fill type index |
468 | function TipTrigger:doPriceDrop(fillLevel, fillType) |
469 | if self.pendingPriceDrop[fillType] ~= nil then |
470 | self.pendingPriceDrop[fillType] = self.pendingPriceDrop[fillType] + self.priceDropPerLiter*fillLevel*self.originalFillTypePrices[fillType] |
471 | self.priceDropTimer = TipTrigger.PRICE_DROP_DELAY |
472 | end |
473 | end |
updatePrices
DescriptionUpdating pricesDefinition
updatePrices(float dt)Arguments
float | dt | time since last call in ms |
478 | function TipTrigger:updatePrices(dt) |
479 | if self.numFillTypesForSelling > 0 and self.hasDynamic then |
480 | -- Only do calculations for products sold at this site. |
481 | local priceRecoverBase = self.priceRecoverPerSecond * dt * 0.001 |
482 | |
483 | for fillType, _ in pairs(self.acceptedFillTypes) do |
484 | self.pricingDynamics[fillType]:update(dt) |
485 | self.fillTypePriceRandomDelta[fillType] = self.pricingDynamics[fillType]:evaluate() |
486 | |
487 | local trend = "normal" |
488 | self.fillTypePriceInfo[fillType] = Utils.clearBit(self.fillTypePriceInfo[fillType], TipTrigger.PRICE_CLIMBING) |
489 | self.fillTypePriceInfo[fillType] = Utils.clearBit(self.fillTypePriceInfo[fillType], TipTrigger.PRICE_FALLING) |
490 | |
491 | if self.pricingDynamics[fillType]:getBaseCurveTrend() == PricingDynamics.TREND_FALLING then |
492 | trend = "falling" |
493 | self.fillTypePriceInfo[fillType] = Utils.setBit(self.fillTypePriceInfo[fillType], TipTrigger.PRICE_FALLING) |
494 | elseif self.pricingDynamics[fillType]:getBaseCurveTrend() == PricingDynamics.TREND_CLIMBING then |
495 | self.fillTypePriceInfo[fillType] = Utils.setBit(self.fillTypePriceInfo[fillType], TipTrigger.PRICE_CLIMBING) |
496 | trend = "climbing" |
497 | end |
498 | |
499 | local priceRecover = priceRecoverBase * self.originalFillTypePrices[fillType] |
500 | self.fillTypePrices[fillType] = math.min(self.fillTypePrices[fillType] + priceRecover, self.originalFillTypePrices[fillType]) |
501 | self.fillTypePriceInfo[fillType] = Utils.clearBit(self.fillTypePriceInfo[fillType], TipTrigger.PRICE_LOW) |
502 | self.fillTypePriceInfo[fillType] = Utils.clearBit(self.fillTypePriceInfo[fillType], TipTrigger.PRICE_HIGH) |
503 | |
504 | local correctedDelta = self.fillTypePriceRandomDelta[fillType] - (self.originalFillTypePrices[fillType] - self.fillTypePrices[fillType]) |
505 | if correctedDelta > self.levelThreshold then |
506 | trend = trend .. " high" |
507 | self.fillTypePriceInfo[fillType] = Utils.setBit(self.fillTypePriceInfo[fillType], TipTrigger.PRICE_HIGH) |
508 | elseif correctedDelta < -self.levelThreshold then |
509 | self.fillTypePriceInfo[fillType] = Utils.setBit(self.fillTypePriceInfo[fillType], TipTrigger.PRICE_LOW) |
510 | trend = trend .. " low" |
511 | end |
512 | end |
513 | end |
514 | end |
getEffectiveFillTypePrice
DescriptionGet fill type price multiplicated with random delta and great demandsDefinition
getEffectiveFillTypePrice(integer fillType)Arguments
integer | fillType | fill type |
float | price | price |
520 | function TipTrigger:getEffectiveFillTypePrice(fillType) |
521 | if self.isServer then |
522 | return ((self.fillTypePrices[fillType] + self.fillTypePriceRandomDelta[fillType]) * self.priceMultipliers[fillType]) |
523 | else |
524 | return self.fillTypePrices[fillType] |
525 | end |
526 | end |
setPriceMultiplier
DescriptionSet price multiplier for fill typeDefinition
setPriceMultiplier(integer fillType, float priceMultiplier)Arguments
integer | fillType | fill type index |
float | priceMultiplier | new price multiplier |
532 | function TipTrigger:setPriceMultiplier(fillType, priceMultiplier) |
533 | self.priceMultipliers[fillType] = priceMultiplier |
534 | end |
setIsInGreatDemand
DescriptionSet great demand for fill typeDefinition
setIsInGreatDemand(integer fillType, boolean isGreatDemand)Arguments
integer | fillType | fill type index |
boolean | isGreatDemand | is great demand |
547 | function TipTrigger:setIsInGreatDemand(fillType, isInGreatDemand) |
548 | if isInGreatDemand then |
549 | self.fillTypePriceInfo[fillType] = Utils.setBit(self.fillTypePriceInfo[fillType], TipTrigger.PRICE_GREAT_DEMAND) |
550 | self.isGreatDemandActive = true |
551 | self.greatDemandFillType = fillType |
552 | else |
553 | if self.greatDemandFillType ~= nil and self.fillTypePriceInfo[self.greatDemandFillType] ~= nil then |
554 | self.fillTypePriceInfo[self.greatDemandFillType] = Utils.clearBit(self.fillTypePriceInfo[self.greatDemandFillType], TipTrigger.PRICE_GREAT_DEMAND) |
555 | end |
556 | self.isGreatDemandActive = false |
557 | self.greatDemandFillType = FillUtil.FILLTYPE_UNKNOWN |
558 | end |
559 | |
560 | -- raise dirty flag to sync great demand values |
561 | self:raiseDirtyFlags(self.tipTriggerDirtyFlag); |
562 | self.priceSyncTimer = self.priceSyncTimerDuration |
563 | end |
getPriceMultiplier
DescriptionGet price multiplier for fill typeDefinition
getPriceMultiplier(integer fillType)Arguments
integer | fillType | fill type index |
float | priceMultiplier | price multiplier |
569 | function TipTrigger:getPriceMultiplier(fillType) |
570 | return self.priceMultipliers[fillType] |
571 | end |
getTotalReceived
DescriptionGet total received fill level for fill typeDefinition
getTotalReceived(integer fillType)Arguments
integer | fillType | fill type index |
float | totalReceived | total received fill level |
577 | function TipTrigger:getTotalReceived(fillType) |
578 | return self.totalReceived[fillType] |
579 | end |
getTotalPaid
DescriptionGet total paid price for fill typeDefinition
getTotalPaid(integer fillType)Arguments
integer | fillType | fill type index |
float | totalPaid | total paid price |
585 | function TipTrigger:getTotalPaid(fillType) |
586 | return self.totalPaid[fillType] |
587 | end |
getCurrentPricingTrend
DescriptionGet price trend for fill typeDefinition
getCurrentPricingTrend(integer fillType)Arguments
integer | fillType | fill type index |
float | priceTrend | price trend |
593 | function TipTrigger:getCurrentPricingTrend(fillType) |
594 | return self.fillTypePriceInfo[fillType] |
595 | end |
readStream
DescriptionCalled on client side on joinDefinition
readStream(integer streamId, table connection)Arguments
integer | streamId | stream ID |
table | connection | connection |
601 | function TipTrigger:readStream(streamId, connection) |
602 | TipTrigger:superClass().readStream(self, streamId, connection); |
603 | if connection:getIsServer() then |
604 | local numFillTypes = streamReadUInt8(streamId) |
605 | for i=1, numFillTypes do |
606 | local fillType = streamReadUInt8(streamId) |
607 | self.fillTypePrices[fillType] = streamReadUInt16(streamId)/1000 |
608 | self.fillTypePriceInfo[fillType] = streamReadUIntN(streamId, 6) |
609 | end |
610 | end |
611 | end |
writeStream
DescriptionCalled on server side on joinDefinition
writeStream(integer streamId, table connection)Arguments
integer | streamId | stream ID |
table | connection | connection |
617 | function TipTrigger:writeStream(streamId, connection) |
618 | TipTrigger:superClass().writeStream(self, streamId, connection); |
619 | if not connection:getIsServer() then |
620 | streamWriteUInt8(streamId, self.numFillTypesForSelling) |
621 | if self.numFillTypesForSelling > 0 then |
622 | for fillType, _ in pairs(self.acceptedFillTypes) do |
623 | if self.originalFillTypePrices[fillType] > 0 then |
624 | streamWriteUInt8(streamId, fillType) |
625 | streamWriteUInt16(streamId, self:getEffectiveFillTypePrice(fillType)*1000) -- converting price to int |
626 | streamWriteUIntN(streamId, self:getCurrentPricingTrend(fillType), 6) |
627 | end |
628 | end |
629 | end |
630 | end |
631 | end |
readUpdateStream
DescriptionCalled on client side on updateDefinition
readUpdateStream(integer streamId, integer timestamp, table connection)Arguments
integer | streamId | stream ID |
integer | timestamp | timestamp |
table | connection | connection |
638 | function TipTrigger:readUpdateStream(streamId, timestamp, connection) |
639 | TipTrigger:superClass().readUpdateStream(self, streamId, timestamp, connection); |
640 | if connection:getIsServer() then |
641 | if streamReadBool(streamId) then |
642 | TipTrigger.readStream(self, streamId, connection) |
643 | end |
644 | end |
645 | end |
writeUpdateStream
DescriptionCalled on server side on updateDefinition
writeUpdateStream(integer streamId, table connection, integer dirtyMask)Arguments
integer | streamId | stream ID |
table | connection | connection |
integer | dirtyMask | dirty mask |
652 | function TipTrigger:writeUpdateStream(streamId, connection, dirtyMask) |
653 | TipTrigger:superClass().writeUpdateStream(self, streamId, connection, dirtyMask); |
654 | if not connection:getIsServer() then |
655 | if streamWriteBool(streamId, bitAND(dirtyMask, self.tipTriggerDirtyFlag) ~= 0) then |
656 | TipTrigger.writeStream(self, streamId, connection) |
657 | end |
658 | end |
659 | end |
loadFromAttributesAndNodes
DescriptionLoading from attributes and nodesDefinition
loadFromAttributesAndNodes(integer xmlFile, string key)Arguments
integer | xmlFile | id of xml object |
string | key | key |
boolean | success | success |
666 | function TipTrigger:loadFromAttributesAndNodes(xmlFile, key) |
667 | local i=0 |
668 | while true do |
669 | local statsKey = string.format(key..".stats(%d)", i) |
670 | if not hasXMLProperty(xmlFile, statsKey) then |
671 | break |
672 | end |
673 | local fillTypeStr = getXMLString(xmlFile, statsKey.."#fillType") |
674 | local fillType = FillUtil.fillTypeNameToInt[fillTypeStr] |
675 | if fillType ~= nil and self.acceptedFillTypes[fillType] then |
676 | self.totalReceived[fillType] = Utils.getNoNil(getXMLFloat(xmlFile, statsKey.."#received"), 0) |
677 | self.totalPaid[fillType] = Utils.getNoNil(getXMLFloat(xmlFile, statsKey.."#paid"), 0) |
678 | self.pricingDynamics[fillType]:deserialize(xmlFile, statsKey) |
679 | end |
680 | i = i + 1 |
681 | end |
682 | |
683 | return true; |
684 | end; |
getSaveAttributesAndNodes
DescriptionGet save attributes and nodesDefinition
getSaveAttributesAndNodes(string nodeIdent)Arguments
string | nodeIdent | node ident |
string | attributes | attributes |
string | nodes | nodes |
691 | function TipTrigger:getSaveAttributesAndNodes(nodeIdent) |
692 | |
693 | local attributes = ''; |
694 | local nodes = ''; |
695 | |
696 | for fillType, _ in pairs(self.acceptedFillTypes) do |
697 | if self.originalFillTypePrices[fillType] > 0 then |
698 | if nodes ~= '' then |
699 | nodes = nodes.. '\n' |
700 | end |
701 | local fillTypeName = FillUtil.fillTypeIntToName[fillType] |
702 | |
703 | local pricingAttributes, pricingNodes = self.pricingDynamics[fillType]:serialize(nodeIdent..' ') |
704 | if pricingAttributes == nil then |
705 | pricingAttributes = "" |
706 | end; |
707 | |
708 | nodes = nodes .. nodeIdent..'<stats fillType="'..fillTypeName..'" received="'..self.totalReceived[fillType]..'" paid="'..self.totalPaid[fillType]..'" '..pricingAttributes..'>'; |
709 | |
710 | if pricingNodes ~= nil and pricingNodes ~= "" then |
711 | nodes = nodes.."\n"..pricingNodes; |
712 | end; |
713 | nodes = nodes ..'\n' .. nodeIdent .. '</stats>' |
714 | end |
715 | end |
716 | |
717 | return attributes, nodes; |
718 | end; |
update
DescriptionUpdateDefinition
update(float dt)Arguments
float | dt | time since last call in ms |
723 | function TipTrigger:update(dt) |
724 | if self.lastMoneyChange > 0 then |
725 | self.lastMoneyChange = self.lastMoneyChange - 1 |
726 | if self.lastMoneyChange == 0 then |
727 | g_currentMission:showMoneyChange(self.moneyChangeId, g_i18n:getText("finance_"..self.lastIncomeName)) |
728 | end |
729 | end |
730 | end |
updateTick
DescriptionupdateTickDefinition
updateTick(float dt)Arguments
float | dt | time since last call in ms |
735 | function TipTrigger:updateTick(dt) |
736 | if self.isServer and self.isSellingPoint then |
737 | self:updatePrices(dt * g_currentMission.missionInfo.timeScale) |
738 | |
739 | if self.priceDropTimer > 0.0 then |
740 | self.priceDropTimer = math.max(self.priceDropTimer - dt, 0.0) |
741 | end |
742 | |
743 | if self.priceDropTimer <= 0.0 then |
744 | for fillType,_ in pairs(self.acceptedFillTypes) do |
745 | if not (self.isGreatDemandActive and self.greatDemandFillType == fillType) then |
746 | if self.pendingPriceDrop[fillType] > 0.0 then |
747 | self:executePriceDrop(self.pendingPriceDrop[fillType], fillType) |
748 | self.pendingPriceDrop[fillType] = 0.0 |
749 | end |
750 | end |
751 | end |
752 | end |
753 | |
754 | if self.hasDynamic then |
755 | self.priceSyncTimer = self.priceSyncTimer - dt |
756 | if self.priceSyncTimer < 0 then |
757 | self:raiseDirtyFlags(self.tipTriggerDirtyFlag); |
758 | self.priceSyncTimer = self.priceSyncTimerDuration |
759 | end |
760 | end |
761 | end |
762 | |
763 | if self.isServer then |
764 | local object = next(self.objectsInTrigger); |
765 | if object ~= nil then |
766 | if not entityExists(object.nodeId) then |
767 | self.objectsInTrigger[object] = nil; |
768 | object = nil; |
769 | end |
770 | end |
771 | if object ~= nil then |
772 | local fillType = object:getFillType(); |
773 | local fillLevel = object:getFillLevel(); |
774 | if fillLevel > 0 then |
775 | if self:getAllowFillTypeFromTool(fillType, TipTrigger.TOOL_TYPE_PALLET) then |
776 | local changed = self:addFillLevelFromTool(object, math.min(fillLevel, object.fillablePalletUnloadSpeed*dt), fillType, TipTrigger.TOOL_TYPE_PALLET); |
777 | object:setFillLevel(fillLevel - changed); |
778 | end |
779 | end |
780 | end |
781 | end |
782 | end |
getAllowFillTypeFromTool
DescriptionCheck if fill type from tool is allowedDefinition
getAllowFillTypeFromTool(integer fillType, integer toolType)Arguments
integer | fillType | fill type index |
integer | toolType | tool type index |
boolean | isAllowed | fill type is allowed |
789 | function TipTrigger:getAllowFillTypeFromTool(fillType, toolType) |
790 | if self.acceptedFillTypes[fillType] then |
791 | if self.allowedToolTypes[fillType][toolType] then |
792 | if self.tipTriggerTargets == nil then |
793 | return true; |
794 | end |
795 | |
796 | for target,_ in pairs(self.tipTriggerTargets) do |
797 | if target:allowFillType(fillType) and target:getFreeCapacity(fillType) > 0 then |
798 | return true |
799 | end |
800 | end |
801 | end |
802 | end |
803 | |
804 | return false |
805 | end |
addFillLevelFromTool
DescriptionAdd fill level from tool to triggerDefinition
addFillLevelFromTool(table object, float fillDelta, integer fillType, integer toolType)Arguments
table | object | object |
float | fillDelta | delta to fill |
integer | fillType | fill type index |
integer | toolType | tool type index |
float | fillDelta | real fill delta |
814 | function TipTrigger:addFillLevelFromTool(object, fillDelta, fillType, toolType) |
815 | local changed = 0 |
816 | if fillDelta > 0 then |
817 | local tipTriggerTarget = nil |
818 | |
819 | if self.handleFilling then |
820 | if self.tipTriggerTargets == nil then |
821 | self:sellFillType(fillDelta, fillType) |
822 | changed = fillDelta |
823 | else |
824 | for target,_ in pairs(self.tipTriggerTargets) do |
825 | if target:allowFillType(fillType) and target:getFreeCapacity(fillType) > 0 then |
826 | if tipTriggerTarget == nil then |
827 | tipTriggerTarget = target |
828 | end |
829 | local maxFillDelta = math.min(fillDelta - changed, target:getFreeCapacity(fillType)) |
830 | changed = changed + maxFillDelta; |
831 | target:setFillLevel(target:getFillLevel(fillType)+maxFillDelta, fillType, object, self) |
832 | |
833 | -- if remain == 0 break, else try to find another target to fill the remaining fillType |
834 | if changed >= fillDelta then |
835 | break |
836 | end |
837 | end |
838 | end |
839 | end |
840 | else |
841 | changed = fillDelta |
842 | end |
843 | |
844 | -- TOUR SPECIFIC STUFF |
845 | if g_currentMission.tourIconsBase ~= nil and g_currentMission.tourIconsBase.visible then |
846 | if self.stationName == "StationGrainElevator" and not g_currentMission.tourIconsBase.soldStuffAtGrainElevator then |
847 | g_currentMission.tourIconsBase.soldStuffAtGrainElevator = true |
848 | end |
849 | end |
850 | |
851 | for _, listener in pairs(self.updateEventListeners) do |
852 | listener:onUpdateEvent(self, fillDelta, fillType, object, tipTriggerTarget) |
853 | end |
854 | end |
855 | |
856 | return changed |
857 | end |
sellFillType
DescriptionSell fill type in tip triggerDefinition
sellFillType(float fillDelta, integer fillType)Arguments
float | fillDelta | delta fill level to sell |
integer | fillType | fill type index |
863 | function TipTrigger:sellFillType(fillDelta, fillType, userId) |
864 | if not self.priceDropDisabled[fillType] then |
865 | self:doPriceDrop(fillDelta, fillType) |
866 | end |
867 | -- update total amount of this fill type |
868 | local desc = FillUtil.fillTypeIndexToDesc[fillType] |
869 | desc.totalAmount = desc.totalAmount + fillDelta |
870 | |
871 | self.totalReceived[fillType] = self.totalReceived[fillType] + fillDelta |
872 | |
873 | local price = fillDelta * self:getEffectiveFillTypePrice(fillType) |
874 | self.totalPaid[fillType] = self.totalPaid[fillType] + price |
875 | self.lastIncomeName = self:getIncomeNameForFillType(fillType) |
876 | |
877 | if userId ~= nil then |
878 | g_currentMission:addMoney(price, userId, self.lastIncomeName) |
879 | else |
880 | g_currentMission:addSharedMoney(price, self.lastIncomeName) |
881 | end |
882 | g_currentMission:addMoneyChange(price, self.moneyChangeId) |
883 | self.lastMoneyChange = 30 |
884 | |
885 | return price |
886 | end |
getIncomeNameForFillType
DescriptionReturns income text for fill typeDefinition
getIncomeNameForFillType(integer fillType)Arguments
integer | fillType | fill type index |
string | incomingName | incoming name of fill type |
892 | function TipTrigger:getIncomeNameForFillType(fillType) |
893 | if fillType == FillUtil.FILLTYPE_WOOL then |
894 | return self.incomeNameWool |
895 | end |
896 | return self.incomeName |
897 | end |
getTipInfoForTrailer
DescriptionReturns tip informations for trailerDefinition
getTipInfoForTrailer(table trailer, integer tipReferencePointIndex)Arguments
table | trailer | trailer to check |
integer | tipReferencePointIndex | tip reference point index |
boolean | isAllowed | is allowed to tip |
float | minDistance | distance from best point to trigger |
integer | bestPoint | nearest tip reference point from trailer |
906 | function TipTrigger:getTipInfoForTrailer(trailer, tipReferencePointIndex) |
907 | local minDistance, bestPoint = self:getTipDistanceFromTrailer(trailer, tipReferencePointIndex) |
908 | |
909 | local isAllowed = false |
910 | local fillTypes = trailer:getCurrentFillTypes() |
911 | if fillTypes ~= nil then |
912 | for _,fillType in pairs(fillTypes) do |
913 | if self:getAllowFillTypeFromTool(fillType, TipTrigger.TOOL_TYPE_TRAILER) then |
914 | isAllowed = true; |
915 | break; |
916 | end |
917 | end |
918 | end |
919 | |
920 | return isAllowed, minDistance, bestPoint |
921 | end |
getTipDistanceFromTrailer
DescriptionReturns distance to nearest tip reference pointDefinition
getTipDistanceFromTrailer(table trailer, integer tipReferencePointIndex)Arguments
table | trailer | trailer |
integer | tipReferencePointIndex | tip reference point index |
float | minDistance | distance to best point |
integer | bestPoint | index of best tip reference point |
929 | function TipTrigger:getTipDistanceFromTrailer(trailer, tipReferencePointIndex) |
930 | |
931 | local minDistance = math.huge |
932 | local bestPoint = nil |
933 | local bestWidth = -1 |
934 | |
935 | local sx, _, sz = getWorldTranslation(self.triggerStartId) |
936 | if self.isAreaTrigger then |
937 | local ex, _, ez = getWorldTranslation(self.triggerEndId) |
938 | local dx, dz = ex-sx, ez-sz |
939 | local length = math.sqrt(dx*dx + dz*dz) |
940 | if length > 0.00001 then |
941 | dx = dx / length |
942 | dz = dz / length |
943 | end |
944 | if tipReferencePointIndex ~= nil then |
945 | local trailerX, _, trailerZ = getWorldTranslation(trailer.tipReferencePoints[tipReferencePointIndex].node) |
946 | return Utils.getDistanceToRectangle2D(trailerX, trailerZ, sx, sz, dx, dz, length, self.triggerWidth), tipReferencePointIndex |
947 | else |
948 | for i,point in pairs(trailer.tipReferencePoints) do |
949 | local trailerX, _, trailerZ = getWorldTranslation(point.node) |
950 | local distance = Utils.getDistanceToRectangle2D(trailerX, trailerZ, sx, sz, dx, dz, length, self.triggerWidth) |
951 | if point.width <= self.triggerTipWidth and point.width > bestWidth then |
952 | -- if the tip point matches the trigger better, then also accept it if the distance does not improve |
953 | if distance <= minDistance+0.001 then |
954 | bestPoint = i |
955 | bestWidth = point.width |
956 | minDistance = distance |
957 | end |
958 | else |
959 | if distance < minDistance then |
960 | bestPoint = i |
961 | minDistance = distance |
962 | end |
963 | end |
964 | end |
965 | end |
966 | else |
967 | if tipReferencePointIndex ~= nil then |
968 | local trailerX, _, trailerZ = getWorldTranslation(trailer.tipReferencePoints[tipReferencePointIndex].node) |
969 | return Utils.vector2Length(trailerX-sx, trailerZ-sz), tipReferencePointIndex |
970 | else |
971 | for i,point in pairs(trailer.tipReferencePoints) do |
972 | local trailerX, _, trailerZ = getWorldTranslation(point.node) |
973 | local distance = Utils.vector2Length(trailerX-sx, trailerZ-sz) |
974 | if point.width <= self.triggerTipWidth and point.width > bestWidth then |
975 | -- if the tip point matches the trigger better, then also accept it if the distance does not improve |
976 | if distance <= minDistance+0.001 then |
977 | bestPoint = i |
978 | bestWidth = point.width |
979 | minDistance = distance |
980 | end |
981 | else |
982 | if distance < minDistance then |
983 | bestPoint = i |
984 | minDistance = distance |
985 | end |
986 | end |
987 | end |
988 | end |
989 | end |
990 | return minDistance, bestPoint |
991 | end |
getNotAllowedText
DescriptionReturns fill type not allowed textDefinition
getNotAllowedText(table fillable, integer toolType)Arguments
table | fillable | fillable object |
integer | toolType | tool type index |
string | notAllowedText | not allowed text |
998 | function TipTrigger:getNotAllowedText(fillable, toolType) |
999 | if not self.suppressWarnings then |
1000 | local fillTypes = fillable:getCurrentFillTypes() |
1001 | if fillTypes ~= nil and next(fillTypes) ~= nil then |
1002 | local hasGenerallyAcceptedFillType = false; |
1003 | local acceptedFillType; |
1004 | local notAcceptedFillTypes = "" |
1005 | local notAcceptedToolFillTypes = "" |
1006 | for _,fillType in pairs(fillTypes) do |
1007 | if self.acceptedFillTypes[fillType] then |
1008 | hasGenerallyAcceptedFillType = true; |
1009 | if self.allowedToolTypes[fillType][toolType] then |
1010 | if acceptedFillType == nil then |
1011 | acceptedFillType = fillType; |
1012 | end |
1013 | else |
1014 | if notAcceptedToolFillTypes ~= "" then |
1015 | notAcceptedToolFillTypes = notAcceptedToolFillTypes .. ", " |
1016 | end |
1017 | notAcceptedToolFillTypes = notAcceptedToolFillTypes .. FillUtil.fillTypeIndexToDesc[fillType].nameI18N |
1018 | end |
1019 | else |
1020 | if notAcceptedFillTypes ~= "" then |
1021 | notAcceptedFillTypes = notAcceptedFillTypes .. ", " |
1022 | end |
1023 | notAcceptedFillTypes = notAcceptedFillTypes .. FillUtil.fillTypeIndexToDesc[fillType].nameI18N |
1024 | end |
1025 | end |
1026 | if acceptedFillType == nil then |
1027 | if hasGenerallyAcceptedFillType then |
1028 | return string.format(g_i18n:getText("warning_notAcceptedTool"), notAcceptedToolFillTypes) |
1029 | else |
1030 | return string.format(g_i18n:getText("warning_notAcceptedHere"), notAcceptedFillTypes) |
1031 | end |
1032 | else |
1033 | if not self:getAllowFillTypeFromTool(acceptedFillType, toolType) then |
1034 | return string.format(g_i18n:getText("warning_noMoreFreeCapacity"), FillUtil.fillTypeIndexToDesc[acceptedFillType].nameI18N) |
1035 | end |
1036 | end |
1037 | end |
1038 | end |
1039 | return nil |
1040 | end |
addTipTriggerTarget
DescriptionAdd target to tip trigger, e.g. a storageDefinition
addTipTriggerTarget(table target, boolean updateFillTypes)Arguments
table | target | target |
boolean | updateFillTypes | update fill types |
1046 | function TipTrigger:addTipTriggerTarget(target, updateFillTypes) |
1047 | if self.tipTriggerTargets == nil then |
1048 | self.tipTriggerTargets = {} |
1049 | end |
1050 | self.tipTriggerTargets[target] = target |
1051 | if target.addTipTrigger ~= nil then |
1052 | target:addTipTrigger(self) |
1053 | end |
1054 | if updateFillTypes == nil or updateFillTypes == true then |
1055 | self:updateFillTypes() |
1056 | end |
1057 | end |
removeTipTriggerTarget
DescriptionRemove target from tip trigger, e.g. a storageDefinition
removeTipTriggerTarget(table target, boolean updateFillTypes)Arguments
table | target | target |
boolean | updateFillTypes | update fill types |
1063 | function TipTrigger:removeTipTriggerTarget(target, updateFillTypes) |
1064 | self.tipTriggerTargets[target] = nil |
1065 | local numTargets = 0 |
1066 | for _, _ in pairs(self.tipTriggerTargets) do |
1067 | numTargets = numTargets + 1 |
1068 | end |
1069 | if numTargets == 0 then |
1070 | self.tipTriggerTargets = nil |
1071 | end |
1072 | if target.removeTipTrigger ~= nil then |
1073 | target:removeTipTrigger(self) |
1074 | end |
1075 | if updateFillTypes == nil or updateFillTypes == true then |
1076 | self:updateFillTypes() |
1077 | end |
1078 | end |
updateFillTypes
DescriptionUpdate available fill typesDefinition
updateFillTypes()Code
1082 | function TipTrigger:updateFillTypes() |
1083 | self.acceptedFillTypes = {} |
1084 | if self.tipTriggerTargets ~= nil then |
1085 | for target,_ in pairs(self.tipTriggerTargets) do |
1086 | if target.fillTypes ~= nil then |
1087 | for fillType,_ in pairs(target.fillTypes) do |
1088 | self:addAcceptedFillType(fillType, 0, false, true, {TipTrigger.TOOL_TYPE_TRAILER, TipTrigger.TOOL_TYPE_SHOVEL, TipTrigger.TOOL_TYPE_PIPE, TipTrigger.TOOL_TYPE_PALLET}); |
1089 | end |
1090 | elseif target.fillUnits ~= nil and target.shovel ~= nil then -- shovel |
1091 | if target.fillUnits[target.shovel.fillUnitIndex] ~= nil then |
1092 | local allowedToolTypes = {TipTrigger.TOOL_TYPE_TRAILER, TipTrigger.TOOL_TYPE_SHOVEL, TipTrigger.TOOL_TYPE_PIPE}; |
1093 | if target.shovel.allowPallets then |
1094 | table.insert(allowedToolTypes, TipTrigger.TOOL_TYPE_PALLET); |
1095 | end; |
1096 | |
1097 | for fillType, _ in pairs(target.fillUnits[target.shovel.fillUnitIndex].fillTypes) do |
1098 | self:addAcceptedFillType(fillType, 0, false, true, allowedToolTypes); |
1099 | end |
1100 | end |
1101 | end |
1102 | end |
1103 | end |
1104 | end |
addUpdateEventListener
DescriptionAdd listener to update listenersDefinition
addUpdateEventListener()Code
1108 | function TipTrigger:addUpdateEventListener(listener) |
1109 | if listener ~= nil then |
1110 | self.updateEventListeners[listener] = listener |
1111 | end |
1112 | end |
removeUpdateEventListener
DescriptionRemove listener from update listenersDefinition
removeUpdateEventListener()Code
1116 | function TipTrigger:removeUpdateEventListener(listener) |
1117 | if listener ~= nil then |
1118 | self.updateEventListeners[listener] = nil |
1119 | end |
1120 | end |
triggerCallback
DescriptionTrigger callbackDefinition
triggerCallback(integer triggerId, integer otherActorId, boolean onEnter, boolean onLeave, boolean onStay, integer otherShapeId)Arguments
integer | triggerId | id of trigger |
integer | otherActorId | id of other actor |
boolean | onEnter | on enter |
boolean | onLeave | on leave |
boolean | onStay | on stay |
integer | otherShapeId | id of other shape |
1130 | function TipTrigger:triggerCallback(triggerId, otherId, onEnter, onLeave, onStay, otherShapeId) |
1131 | if self.isEnabled then |
1132 | local trailer = g_currentMission.objectToTrailer[otherId] |
1133 | if trailer ~= nil and trailer.allowTipDischarge and (not self.isTrainOnly or trailer:isa(RailroadVehicle)) then |
1134 | if onEnter then |
1135 | if g_currentMission.trailerTipTriggers[trailer] == nil then |
1136 | g_currentMission.trailerTipTriggers[trailer] = {} |
1137 | end |
1138 | table.insert(g_currentMission.trailerTipTriggers[trailer], self) |
1139 | |
1140 | if trailer.coverAnimation ~= nil and trailer.autoReactToTrigger == true then |
1141 | trailer:setCoverState(true); |
1142 | end |
1143 | elseif onLeave then |
1144 | local triggers = g_currentMission.trailerTipTriggers[trailer] |
1145 | if triggers ~= nil then |
1146 | for i=1, table.getn(triggers) do |
1147 | if triggers[i] == self then |
1148 | table.remove(triggers, i) |
1149 | if table.getn(triggers) == 0 then |
1150 | g_currentMission.trailerTipTriggers[trailer] = nil |
1151 | end |
1152 | break |
1153 | end |
1154 | end |
1155 | end |
1156 | |
1157 | if trailer.coverAnimation ~= nil and trailer.autoReactToTrigger == true then |
1158 | trailer:setCoverState(false); |
1159 | end |
1160 | end |
1161 | else |
1162 | local object = g_currentMission:getNodeObject(otherId); |
1163 | if object ~= nil and object.setFillLevel ~= nil and object:isa(FillablePallet) then |
1164 | if onEnter then |
1165 | self.objectsInTrigger[object] = Utils.getNoNil(self.objectsInTrigger[object], 0) + 1; |
1166 | elseif onLeave then |
1167 | if self.objectsInTrigger[object] ~= nil then |
1168 | self.objectsInTrigger[object] = self.objectsInTrigger[object] - 1; |
1169 | if self.objectsInTrigger[object] == 0 then |
1170 | self.objectsInTrigger[object] = nil; |
1171 | end |
1172 | end |
1173 | end |
1174 | end |
1175 | end |
1176 | end |
1177 | end |