LUADOC - Farming Simulator 17

Printable Version

TipTrigger

Description
Class for tip trigger
Functions

onCreate

Description
On create tip trigger
Definition
onCreate(integer id)
Arguments
integeridtrigger node id
Code
28function 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
37end

new

Description
Creating tip trigger object
Definition
new(boolean isServer, boolean isClient, table customMt)
Arguments
booleanisServeris server
booleanisClientis client
tablecustomMtcustom metatable (optional)
Return Values
tableinstanceInstance of object
Code
45function 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
63end

load

Description
Load tip trigger
Definition
load(integer id)
Arguments
integeridid of trigger node
Return Values
booleansuccesssuccess
Code
69function 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
333end

delete

Description
Delete tip trigger
Definition
delete()
Code
337function 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)
373end

addAcceptedFillType

Description
Add fill type to tip trigger
Definition
addAcceptedFillType(integer fillType, float priceUnscaled, boolean supportsGreatDemand, boolean disablePriceDrop, table allowedToolTypes)
Arguments
integerfillTypefill type index
floatpriceUnscaledprice unscaled
booleansupportsGreatDemandfill type supports great demands
booleandisablePriceDropdisable price drop
tableallowedToolTypesallowed tool types
Code
382function 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
416end

initPricingDynamics

Description
Initialize pricing dynamics
Definition
initPricingDynamics()

executePriceDrop

Description
Execute price drop
Definition
executePriceDrop(float priceDrop, integer fillType)
Arguments
floatpriceDropprice drop
integerfillTypefill type index
Code
459function 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)
462end

doPriceDrop

Description
Do price drop after TipTrigger.PRICE_DROP_DELAY
Definition
doPriceDrop(float fillLevel, integer fillType)
Arguments
floatfillLevelfill level
integerfillTypefill type index
Code
468function 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
473end

updatePrices

Description
Updating prices
Definition
updatePrices(float dt)
Arguments
floatdttime since last call in ms
Code
478function 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
514end

getEffectiveFillTypePrice

Description
Get fill type price multiplicated with random delta and great demands
Definition
getEffectiveFillTypePrice(integer fillType)
Arguments
integerfillTypefill type
Return Values
floatpriceprice
Code
520function 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
526end

setPriceMultiplier

Description
Set price multiplier for fill type
Definition
setPriceMultiplier(integer fillType, float priceMultiplier)
Arguments
integerfillTypefill type index
floatpriceMultipliernew price multiplier
Code
532function TipTrigger:setPriceMultiplier(fillType, priceMultiplier)
533 self.priceMultipliers[fillType] = priceMultiplier
534end

setIsInGreatDemand

Description
Set great demand for fill type
Definition
setIsInGreatDemand(integer fillType, boolean isGreatDemand)
Arguments
integerfillTypefill type index
booleanisGreatDemandis great demand
Code
547function 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
563end

getPriceMultiplier

Description
Get price multiplier for fill type
Definition
getPriceMultiplier(integer fillType)
Arguments
integerfillTypefill type index
Return Values
floatpriceMultiplierprice multiplier
Code
569function TipTrigger:getPriceMultiplier(fillType)
570 return self.priceMultipliers[fillType]
571end

getTotalReceived

Description
Get total received fill level for fill type
Definition
getTotalReceived(integer fillType)
Arguments
integerfillTypefill type index
Return Values
floattotalReceivedtotal received fill level
Code
577function TipTrigger:getTotalReceived(fillType)
578 return self.totalReceived[fillType]
579end

getTotalPaid

Description
Get total paid price for fill type
Definition
getTotalPaid(integer fillType)
Arguments
integerfillTypefill type index
Return Values
floattotalPaidtotal paid price
Code
585function TipTrigger:getTotalPaid(fillType)
586 return self.totalPaid[fillType]
587end

getCurrentPricingTrend

Description
Get price trend for fill type
Definition
getCurrentPricingTrend(integer fillType)
Arguments
integerfillTypefill type index
Return Values
floatpriceTrendprice trend
Code
593function TipTrigger:getCurrentPricingTrend(fillType)
594 return self.fillTypePriceInfo[fillType]
595end

readStream

Description
Called on client side on join
Definition
readStream(integer streamId, table connection)
Arguments
integerstreamIdstream ID
tableconnectionconnection
Code
601function 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
611end

writeStream

Description
Called on server side on join
Definition
writeStream(integer streamId, table connection)
Arguments
integerstreamIdstream ID
tableconnectionconnection
Code
617function 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
631end

readUpdateStream

Description
Called on client side on update
Definition
readUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdstream ID
integertimestamptimestamp
tableconnectionconnection
Code
638function 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
645end

writeUpdateStream

Description
Called on server side on update
Definition
writeUpdateStream(integer streamId, table connection, integer dirtyMask)
Arguments
integerstreamIdstream ID
tableconnectionconnection
integerdirtyMaskdirty mask
Code
652function 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
659end

loadFromAttributesAndNodes

Description
Loading from attributes and nodes
Definition
loadFromAttributesAndNodes(integer xmlFile, string key)
Arguments
integerxmlFileid of xml object
stringkeykey
Return Values
booleansuccesssuccess
Code
666function 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;
684end;

getSaveAttributesAndNodes

Description
Get save attributes and nodes
Definition
getSaveAttributesAndNodes(string nodeIdent)
Arguments
stringnodeIdentnode ident
Return Values
stringattributesattributes
stringnodesnodes
Code
691function 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;
718end;

update

Description
Update
Definition
update(float dt)
Arguments
floatdttime since last call in ms
Code
723function 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
730end

updateTick

Description
updateTick
Definition
updateTick(float dt)
Arguments
floatdttime since last call in ms
Code
735function 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
782end

getAllowFillTypeFromTool

Description
Check if fill type from tool is allowed
Definition
getAllowFillTypeFromTool(integer fillType, integer toolType)
Arguments
integerfillTypefill type index
integertoolTypetool type index
Return Values
booleanisAllowedfill type is allowed
Code
789function 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
805end

addFillLevelFromTool

Description
Add fill level from tool to trigger
Definition
addFillLevelFromTool(table object, float fillDelta, integer fillType, integer toolType)
Arguments
tableobjectobject
floatfillDeltadelta to fill
integerfillTypefill type index
integertoolTypetool type index
Return Values
floatfillDeltareal fill delta
Code
814function 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
857end

sellFillType

Description
Sell fill type in tip trigger
Definition
sellFillType(float fillDelta, integer fillType)
Arguments
floatfillDeltadelta fill level to sell
integerfillTypefill type index
Code
863function 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
886end

getIncomeNameForFillType

Description
Returns income text for fill type
Definition
getIncomeNameForFillType(integer fillType)
Arguments
integerfillTypefill type index
Return Values
stringincomingNameincoming name of fill type
Code
892function TipTrigger:getIncomeNameForFillType(fillType)
893 if fillType == FillUtil.FILLTYPE_WOOL then
894 return self.incomeNameWool
895 end
896 return self.incomeName
897end

getTipInfoForTrailer

Description
Returns tip informations for trailer
Definition
getTipInfoForTrailer(table trailer, integer tipReferencePointIndex)
Arguments
tabletrailertrailer to check
integertipReferencePointIndextip reference point index
Return Values
booleanisAllowedis allowed to tip
floatminDistancedistance from best point to trigger
integerbestPointnearest tip reference point from trailer
Code
906function 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
921end

getTipDistanceFromTrailer

Description
Returns distance to nearest tip reference point
Definition
getTipDistanceFromTrailer(table trailer, integer tipReferencePointIndex)
Arguments
tabletrailertrailer
integertipReferencePointIndextip reference point index
Return Values
floatminDistancedistance to best point
integerbestPointindex of best tip reference point
Code
929function 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
991end

getNotAllowedText

Description
Returns fill type not allowed text
Definition
getNotAllowedText(table fillable, integer toolType)
Arguments
tablefillablefillable object
integertoolTypetool type index
Return Values
stringnotAllowedTextnot allowed text
Code
998function 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
1040end

addTipTriggerTarget

Description
Add target to tip trigger, e.g. a storage
Definition
addTipTriggerTarget(table target, boolean updateFillTypes)
Arguments
tabletargettarget
booleanupdateFillTypesupdate fill types
Code
1046function 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
1057end

removeTipTriggerTarget

Description
Remove target from tip trigger, e.g. a storage
Definition
removeTipTriggerTarget(table target, boolean updateFillTypes)
Arguments
tabletargettarget
booleanupdateFillTypesupdate fill types
Code
1063function 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
1078end

updateFillTypes

Description
Update available fill types
Definition
updateFillTypes()
Code
1082function 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
1104end

addUpdateEventListener

Description
Add listener to update listeners
Definition
addUpdateEventListener()
Code
1108function TipTrigger:addUpdateEventListener(listener)
1109 if listener ~= nil then
1110 self.updateEventListeners[listener] = listener
1111 end
1112end

removeUpdateEventListener

Description
Remove listener from update listeners
Definition
removeUpdateEventListener()
Code
1116function TipTrigger:removeUpdateEventListener(listener)
1117 if listener ~= nil then
1118 self.updateEventListeners[listener] = nil
1119 end
1120end

triggerCallback

Description
Trigger callback
Definition
triggerCallback(integer triggerId, integer otherActorId, boolean onEnter, boolean onLeave, boolean onStay, integer otherShapeId)
Arguments
integertriggerIdid of trigger
integerotherActorIdid of other actor
booleanonEnteron enter
booleanonLeaveon leave
booleanonStayon stay
integerotherShapeIdid of other shape
Code
1130function 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
1177end