Sprache Deutsch Language English

Script Dokumentation LS 2015 - TipTrigger (Patch 1.3)

Script Dokumentation Übersicht

scripts/triggers/TipTrigger.lua

Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.
2
3TipTrigger = {};
4
5local TipTrigger_mt = Class(TipTrigger, Object);
6
7InitStaticObjectClass(TipTrigger, "TipTrigger", ObjectIds.OBJECT_TIP_TRIGGER);
8
9function TipTrigger:onCreate(id)
10 local trigger = TipTrigger:new(g_server ~= nil, g_client ~= nil);
11 local index = g_currentMission:addOnCreateLoadedObject(trigger);
12 trigger:load(id);
13 trigger:register(true);
14end;
15
16function TipTrigger:new(isServer, isClient, customMt)
17 if customMt == nil then
18 customMt = TipTrigger_mt;
19 end
20 local self = Object:new(isServer, isClient, customMt);
21 self.triggerId = 0;
22 self.rootNode = 0;
23 g_currentMission:addTipTrigger(self);
24 return self;
25end;
26
27function TipTrigger:load(id)
28
29 self.rootNode = id;
30 self.triggerId = Utils.indexToObject(id, getUserAttribute(id, "triggerIndex"));
31 if self.triggerId == nil then
32 self.triggerId = id;
33 end
34 addTrigger(self.triggerId, "triggerCallback", self);
35
36 self.appearsOnPDA = Utils.getNoNil(getUserAttribute(id, "appearsOnPDA"), false);
37 self.isFarmTrigger = Utils.getNoNil(getUserAttribute(id, "isFarmTrigger"), false);
38 self.suppressWarnings = Utils.getNoNil(getUserAttribute(id, "suppressWarnings"), false);
39 self.stationName = Utils.getNoNil(getUserAttribute(id, "stationName"), "Station");
40
41 self.isAreaTrigger = Utils.getNoNil(getUserAttribute(id, "isAreaTrigger"), false);
42 if self.isAreaTrigger then
43 self.triggerStartId = getChildAt(id, 0);
44 self.triggerEndId = getChildAt(id, 1);
45 self.triggerWidth = Utils.getNoNil(getUserAttribute(id, "triggerWidth"), 3);
46 else
47 self.triggerStartId = self.triggerId;
48 end
49
50 self.triggerTipWidth = Utils.getNoNil(getUserAttribute(id, "triggerTipWidth"), math.huge);
51
52 if self.priceMultipliers == nil or self.acceptedFillTypes == nil then
53 self.acceptedFillTypes = {};
54 self.priceMultipliers = {};
55
56 local fillTypes = getUserAttribute(id, "fillTypes");
57 if fillTypes == nil then
58 fillTypes = getUserAttribute(id, "fruitTypes");
59 end
60 local priceMultipliersString = getUserAttribute(id, "priceMultipliers");
61 if fillTypes ~= nil then
62 local types = Utils.splitString(" ", fillTypes);
63
64 local multipliers = {};
65 if priceMultipliersString ~= nil then
66 multipliers = Utils.splitString(" ", priceMultipliersString);
67 elseif not self.isFarmTrigger and self.defaultPriceMultiplier == nil then
68 print("Error: Missing priceMultipliers string user attribute for TipTrigger "..getName(id));
69 end;
70 for k,v in pairs(types) do
71 local desc = Fillable.fillTypeNameToDesc[v];
72 if desc ~= nil then
73 self.acceptedFillTypes[desc.index] = true;
74 self.priceMultipliers[desc.index] = tonumber(multipliers[k]);
75 if self.priceMultipliers[desc.index] == nil then
76 self.priceMultipliers[desc.index] = Utils.getNoNil(self.defaultPriceMultiplier, 0);
77 if not self.isFarmTrigger and self.defaultPriceMultiplier == nil then
78 print("Error: "..k.."th priceMultiplier is invalid in TipTrigger "..getName(id));
79 end;
80 end;
81 end;
82 end;
83 end;
84 end
85
86 local movingIndex = getUserAttribute(id, "movingIndex");
87 if movingIndex ~= nil then
88 local movingRootNode = id;
89 if self.triggerId == id then
90 movingRootNode = getParent(id);
91 end
92 self.movingId = Utils.indexToObject(movingRootNode, movingIndex);
93 if self.movingId ~= nil then
94 self.moveMinY = Utils.getNoNil(getUserAttribute(id, "moveMinY"), 0);
95 self.moveMaxY = Utils.getNoNil(getUserAttribute(id, "moveMaxY"), 0);
96 self.moveScale = Utils.getNoNil(getUserAttribute(id, "moveScale"), 0.001)*0.01;
97 self.moveBackScale = (self.moveMaxY-self.moveMinY)/Utils.getNoNil(getUserAttribute(id, "moveBackTime"), 10000);
98 end;
99 end;
100
101 self.forwardFillLevel = Utils.getNoNil(getUserAttribute(id, "forwardFillLevel"), false);
102
103 if self.appearsOnPDA then
104
105 local mapPosition = id;
106 local mapPositionIndex = getUserAttribute(id, "mapPositionIndex");
107 if mapPositionIndex ~= nil then
108 mapPosition = Utils.indexToObject(id, mapPositionIndex);
109 if mapPosition == nil then
110 mapPosition = id;
111 end;
112 end;
113
114 local x, _, z = getWorldTranslation(mapPosition);
115
116 local fullViewName = self.stationName;
117 if g_i18n:hasText(fullViewName) then
118 fullViewName = g_i18n:getText(fullViewName)
119 end;
120 self.mapHotspot = g_currentMission.ingameMap:createMapHotspot("", "dataS2/menu/hud/hud_pda_spot_tipPlaceGold.png", x, z, nil, nil, false, false, true, 0, true);
121 self.mapHotspot.fullViewName = fullViewName;
122 end;
123
124 self.isEnabled = true;
125
126 self.updateEventListeners = {}
127
128 self.tipTriggerDirtyFlag = self:getNextDirtyFlag();
129
130 self.moneyChangeId = getMoneyTypeId();
131 self.lastMoneyChange = -1;
132
133 return true;
134end;
135
136function TipTrigger:delete()
137 if self.mapHotspot ~= nil then
138 g_currentMission.ingameMap:deleteMapHotspot(self.mapHotspot);
139 end;
140 for trailer,triggers in pairs(g_currentMission.trailerTipTriggers) do
141 if triggers ~= nil then
142 for i=1, table.getn(triggers) do
143 if triggers[i] == self then
144 table.remove(triggers, i);
145 if table.getn(triggers) == 0 then
146 g_currentMission.trailerTipTriggers[trailer] = nil;
147 end;
148 end;
149 end;
150 end;
151 end;
152 g_currentMission:removeTipTrigger(self);
153 if self.triggerId ~= 0 then
154 removeTrigger(self.triggerId);
155 end
156 if self.rootNode ~= 0 then
157 delete(self.rootNode);
158 end
159 TipTrigger:superClass().delete(self);
160end;
161
162function TipTrigger:readStream(streamId, connection)
163 if connection:getIsServer() then
164 if self.movingId ~= nil then
165 local x,y,z = getTranslation(self.movingId);
166 y = streamReadFloat32(streamId);
167 setTranslation(self.movingId, x, y, z);
168 end;
169 end;
170end;
171
172function TipTrigger:writeStream(streamId, connection)
173 if not connection:getIsServer() then
174 if self.movingId ~= nil then
175 local x,y,z = getTranslation(self.movingId);
176 streamWriteFloat32(streamId, y);
177 end;
178 end;
179end;
180
181function TipTrigger:readUpdateStream(streamId, timestamp, connection)
182 self:readStream(streamId, connection);
183end;
184
185function TipTrigger:writeUpdateStream(streamId, connection, dirtyMask)
186 self:writeStream(streamId, connection);
187end;
188
189function TipTrigger:update(dt)
190 if self.movingId ~= nil then
191 local x,y,z = getTranslation(self.movingId);
192 local newY = math.max(y-dt*self.moveBackScale, self.moveMinY);
193 setTranslation(self.movingId, x, newY, z);
194 end;
195
196 if self.lastMoneyChange > 0 then
197 self.lastMoneyChange = self.lastMoneyChange - 1;
198 if self.lastMoneyChange == 0 then
199 g_currentMission:showMoneyChange(self.moneyChangeId);
200 end;
201 end;
202end;
203
204function TipTrigger:updateMoving(delta)
205 if self.movingId ~= nil and self.isServer then
206 local x,y,z = getTranslation(self.movingId);
207 local newY = math.min(y+delta*self.moveScale, self.moveMaxY);
208 setTranslation(self.movingId, x, newY, z);
209 self:raiseDirtyFlags(self.tipTriggerDirtyFlag);
210 end;
211end;
212
213function TipTrigger:updateTrailerTipping(trailer, fillDelta, fillType)
214 if fillDelta < 0 then
215 if not self.forwardFillLevel then
216 if self.isFarmTrigger then
217 -- put load into storage
218 local siloFillType = fillType;
219 if fillType == Fillable.FILLTYPE_DRYGRASS then
220 siloFillType = Fillable.FILLTYPE_GRASS
221 end;
222
223 g_currentMission:setSiloAmount(siloFillType, g_currentMission:getSiloAmount(siloFillType)- fillDelta);
224
225 else
226
227 -- update total amount of this fill type
228 local desc = Fillable.fillTypeIndexToDesc[fillType];
229 desc.totalAmount = desc.totalAmount - fillDelta;
230
231 -- increase money according to price of current fill type
232 local priceMultiplier = self.priceMultipliers[fillType];
233
234 local difficultyMultiplier = math.max(2 * (3 - g_currentMission.missionStats.difficulty), 1); -- 1 2 4
235 local greatDemandMultiplier = 1;
236
237 -- check if a great demand pertaining to this fill type / station is currently running
238 local greatDemand = g_currentMission.economyManager:getCurrentGreatDemand(self.stationName, fillType);
239 if greatDemand ~= nil then
240 greatDemandMultiplier = greatDemand.demandMultiplier;
241 end;
242
243 local money = Fillable.fillTypeIndexToDesc[fillType].pricePerLiter * priceMultiplier * difficultyMultiplier * greatDemandMultiplier * -fillDelta;
244 --g_currentMission.missionStats.money = g_currentMission.missionStats.money + money;
245 g_currentMission:addSharedMoney(money, "harvestIncome");
246 g_currentMission:addMoneyChange(money, self.moneyChangeId);
247 self.lastMoneyChange = 30;
248
249 -- TOUR SPECIFIC STUFF
250 if g_currentMission.tourIconsBase ~= nil and g_currentMission.tourIconsBase.visible then
251 if self.stationName == "StationGrainElevator" and not g_currentMission.tourIconsBase.soldStuffAtGrainElevator then
252 g_currentMission.tourIconsBase.soldStuffAtGrainElevator = true;
253 end;
254 end;
255
256 end;
257 end;
258
259 for _, listener in pairs(self.updateEventListeners) do
260 listener:onUpdateEvent(self, fillDelta, fillType, trailer);
261 end;
262
263 self:updateMoving(-fillDelta);
264 end
265end
266
267function TipTrigger:getTipInfoForTrailer(trailer, tipReferencePointIndex)
268 local minDistance, bestPoint = self:getTipDistanceFromTrailer(trailer, tipReferencePointIndex);
269
270 local isAllowed = false;
271 if self.acceptedFillTypes[trailer.currentFillType] then
272 isAllowed = true;
273 end
274
275 return isAllowed, minDistance, bestPoint;
276end
277
278function TipTrigger:getTipDistanceFromTrailer(trailer, tipReferencePointIndex)
279
280 local minDistance = math.huge;
281 local bestPoint = nil;
282 local bestWidth = -1;
283
284 local sx, _, sz = getWorldTranslation(self.triggerStartId);
285 if self.isAreaTrigger then
286 local ex, _, ez = getWorldTranslation(self.triggerEndId);
287 local dx, dz = ex-sx, ez-sz;
288 local length = math.sqrt(dx*dx + dz*dz);
289 if length > 0.00001 then
290 dx = dx / length;
291 dz = dz / length;
292 end
293 if tipReferencePointIndex ~= nil then
294 local trailerX, _, trailerZ = getWorldTranslation(trailer.tipReferencePoints[tipReferencePointIndex].node);
295 return Utils.getDistanceToRectangle2D(trailerX, trailerZ, sx, sz, dx, dz, length, self.triggerWidth), tipReferencePointIndex;
296 else
297 for i,point in pairs(trailer.tipReferencePoints) do
298 local trailerX, _, trailerZ = getWorldTranslation(point.node);
299 local distance = Utils.getDistanceToRectangle2D(trailerX, trailerZ, sx, sz, dx, dz, length, self.triggerWidth);
300 if point.width <= self.triggerTipWidth and point.width > bestWidth then
301 -- if the tip point matches the trigger better, then also accept it if the distance does not improve
302 if distance <= minDistance+0.001 then
303 bestPoint = i;
304 bestWidth = point.width;
305 minDistance = distance;
306 end
307 else
308 if distance < minDistance then
309 bestPoint = i;
310 minDistance = distance;
311 end
312 end
313 end
314 end
315 else
316 if tipReferencePointIndex ~= nil then
317 local trailerX, _, trailerZ = getWorldTranslation(trailer.tipReferencePoints[tipReferencePointIndex].node);
318 return Utils.vector2Length(trailerX-sx, trailerZ-sz), tipReferencePointIndex;
319 else
320 for i,point in pairs(trailer.tipReferencePoints) do
321 local trailerX, _, trailerZ = getWorldTranslation(point.node);
322 local distance = Utils.vector2Length(trailerX-sx, trailerZ-sz);
323 if point.width <= self.triggerTipWidth and point.width > bestWidth then
324 -- if the tip point matches the trigger better, then also accept it if the distance does not improve
325 if distance <= minDistance+0.001 then
326 bestPoint = i;
327 bestWidth = point.width;
328 minDistance = distance;
329 end
330 else
331 if distance < minDistance then
332 bestPoint = i;
333 minDistance = distance;
334 end
335 end
336 end
337 end
338 end
339 return minDistance, bestPoint;
340end;
341
342function TipTrigger:getNoAllowedText(trailer)
343 if not self.suppressWarnings and trailer.currentFillType ~= Fillable.FILLTYPE_UNKNOWN and not self.acceptedFillTypes[trailer.currentFillType] then
344 return Fillable.fillTypeIndexToDesc[trailer.currentFillType].nameI18N .. g_i18n:getText("notAcceptedHere");
345 end
346 return nil;
347end
348
349function TipTrigger:addUpdateEventListener(listener)
350 if listener ~= nil then
351 self.updateEventListeners[listener] = listener;
352 end;
353end;
354
355function TipTrigger:removeUpdateEventListener(listener)
356 if listener ~= nil then
357 self.updateEventListeners[listener] = nil;
358 end;
359end;
360
361function TipTrigger:triggerCallback(triggerId, otherId, onEnter, onLeave, onStay, otherShapeId)
362 if self.isEnabled then
363 if onEnter then
364 local trailer = g_currentMission.objectToTrailer[otherShapeId];
365 if trailer ~= nil and trailer.allowTipDischarge then
366 if g_currentMission.trailerTipTriggers[trailer] == nil then
367 g_currentMission.trailerTipTriggers[trailer] = {};
368 end;
369 table.insert(g_currentMission.trailerTipTriggers[trailer], self);
370 end;
371 elseif onLeave then
372 local trailer = g_currentMission.objectToTrailer[otherShapeId];
373 if trailer ~= nil and trailer.allowTipDischarge then
374 local triggers = g_currentMission.trailerTipTriggers[trailer];
375 if triggers ~= nil then
376 for i=1, table.getn(triggers) do
377 if triggers[i] == self then
378 table.remove(triggers, i);
379 if table.getn(triggers) == 0 then
380 g_currentMission.trailerTipTriggers[trailer] = nil;
381 end;
382 break;
383 end;
384 end;
385 end;
386 end;
387 end;
388 end;
389end;
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
Script Dokumentation Übersicht