Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1 | -- |
2 | -- Washable |
3 | -- This is the specialization for all washable vehicles |
4 | -- |
5 | -- @author Manuel Leithner |
6 | -- @date 30/07/14 |
7 | -- |
8 | -- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved. |
9 | -- |
10 | -- <washable dirtDuration="60" washDuration="1" workMultiplier="10"/> |
11 | |
12 | Washable = {}; |
13 | |
14 | function Washable.prerequisitesPresent(specializations) |
15 | return true; |
16 | end; |
17 | |
18 | function Washable:preLoad(xmlFile) |
19 | assert(self.setDirtAmount == nil, "Washable needs to be the first specialization which implements setDirtAmount"); |
20 | self.setDirtAmount = Washable.setDirtAmount; |
21 | assert(self.getDirtAmount == nil, "Washable needs to be the first specialization which implements getDirtAmount"); |
22 | self.getDirtAmount = Washable.getDirtAmount; |
23 | assert(self.getDirtMultiplier == nil, "Washable needs to be the first specialization which implements getDirtMultiplier"); |
24 | self.getDirtMultiplier = Washable.getDirtMultiplier; |
25 | end; |
26 | |
27 | function Washable:load(xmlFile) |
28 | |
29 | self.addWashingTrigger = Washable.addWashingTrigger; |
30 | self.removeWashingTrigger = Washable.removeWashingTrigger; |
31 | self.addWashableNode = Washable.addWashableNode; |
32 | self.removeWashableNode = Washable.removeWashableNode; |
33 | |
34 | self.sentDirtAmount = 0; |
35 | self.washableDirtyFlag = self:getNextDirtyFlag(); |
36 | self.dirtAmount = 0; |
37 | |
38 | if hasXMLProperty(xmlFile, "vehicle.washable#dirtDuration") then |
39 | self.washableNodes = {}; |
40 | self.dirtDuration = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.washable#dirtDuration"), 1) * 60 * 1000; |
41 | if self.dirtDuration ~= 0 then |
42 | self.dirtDuration = 1 / self.dirtDuration; -- dirtDuration == 0 disables dirt effect |
43 | end; |
44 | self.washDuration = math.max(Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.washable#washDuration"), 1) * 60 * 1000, 0.00001); -- washDuration == 0 washes vehicle immediately |
45 | self.workMultiplier = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.washable#workMultiplier"), 1); |
46 | self.fieldMultiplier = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.washable#fieldMultiplier"), 2); |
47 | end; |
48 | |
49 | self.washingTriggers = {}; |
50 | end; |
51 | |
52 | function Washable:postLoad(xmlFile) |
53 | -- getting als washable nodes in postLoad to make sure also linked nodes are washable |
54 | if self.washableNodes ~= nil then |
55 | for _, comp in pairs(self.components) do |
56 | self:addWashableNode(comp.node); |
57 | end; |
58 | self:setDirtAmount(0, true); |
59 | end; |
60 | end; |
61 | |
62 | function Washable:readStream(streamId, connection) |
63 | if self.washableNodes ~= nil then |
64 | local dirtAmount = streamReadInt8(streamId) / 100; |
65 | self.sentDirtAmount = dirtAmount; |
66 | self:setDirtAmount(dirtAmount, true); |
67 | end; |
68 | end; |
69 | |
70 | function Washable:writeStream(streamId, connection) |
71 | if self.washableNodes ~= nil then |
72 | streamWriteInt8(streamId, math.floor(self:getDirtAmount()*100)); |
73 | end; |
74 | end; |
75 | |
76 | function Washable:readUpdateStream(streamId, timestamp, connection) |
77 | if connection:getIsServer() and self.washableNodes ~= nil then |
78 | local dirty = streamReadBool(streamId); |
79 | if dirty then |
80 | local dirtAmount = streamReadInt8(streamId) / 100; |
81 | self:setDirtAmount(dirtAmount, true); |
82 | end; |
83 | end; |
84 | end; |
85 | |
86 | function Washable:writeUpdateStream(streamId, connection, dirtyMask) |
87 | if not connection:getIsServer() and self.washableNodes ~= nil then |
88 | if streamWriteBool(streamId, bitAND(dirtyMask, self.washableDirtyFlag) ~= 0) then |
89 | streamWriteInt8(streamId, math.floor(self.sentDirtAmount*100)); |
90 | end; |
91 | end; |
92 | end; |
93 | |
94 | function Washable:delete() |
95 | for _, trigger in pairs(self.washingTriggers) do |
96 | trigger:onVehicleDeleted(self); |
97 | end |
98 | end; |
99 | |
100 | function Washable:mouseEvent(posX, posY, isDown, isUp, button) |
101 | end; |
102 | |
103 | function Washable:keyEvent(unicode, sym, modifier, isDown) |
104 | end; |
105 | |
106 | function Washable:update(dt) |
107 | end; |
108 | |
109 | function Washable:updateTick(dt) |
110 | if self.washableNodes ~= nil then |
111 | if self.isServer then |
112 | if g_currentMission.environment.lastRainScale > 0.1 and g_currentMission.environment.timeSinceLastRain < 30 then |
113 | local amount = self:getDirtAmount(); |
114 | if amount > 0.5 then |
115 | amount = self:getDirtAmount() - (dt/self.washDuration); |
116 | end; |
117 | self:setDirtAmount(amount); |
118 | else |
119 | if self:getIsActive() or self.isActive then |
120 | self:setDirtAmount(self:getDirtAmount() + (dt * self.dirtDuration)*self:getDirtMultiplier()*Washable.getIntervalMultiplier()); |
121 | end; |
122 | end; |
123 | end; |
124 | end; |
125 | end; |
126 | |
127 | function Washable:draw() |
128 | end; |
129 | |
130 | function Washable:setDirtAmount(dirtAmount, force) |
131 | if self.washableNodes ~= nil then |
132 | self.dirtAmount = Utils.clamp(Utils.getNoNil(dirtAmount, self.dirtAmount), 0, 1); |
133 | |
134 | -- only update shader if dirt change sum is about 1% |
135 | if math.abs(self.sentDirtAmount - self.dirtAmount) > 0.01 or force then |
136 | for _, node in pairs(self.washableNodes) do |
137 | local x,_,z,w = getShaderParameter(node, "RDT"); |
138 | setShaderParameter(node, "RDT", x, self.dirtAmount, z, w, false); |
139 | end; |
140 | |
141 | if self.isServer then |
142 | -- use min threshold (0.01) for sync limitation |
143 | self:raiseDirtyFlags(self.washableDirtyFlag); |
144 | self.sentDirtAmount = self.dirtAmount; |
145 | end; |
146 | end; |
147 | end; |
148 | end; |
149 | |
150 | function Washable:addWashableNode(node) |
151 | if self.washableNodes ~= nil and node ~= nil then |
152 | Utils.getNodesByShaderParam(node, "RDT", self.washableNodes); |
153 | end; |
154 | end; |
155 | |
156 | function Washable:removeWashableNode(node) |
157 | if self.washableNodes ~= nil and node ~= nil then |
158 | self.washableNodes[node] = nil; |
159 | end; |
160 | end; |
161 | |
162 | function Washable:getDirtAmount(superFunc) |
163 | return self.dirtAmount; |
164 | end; |
165 | |
166 | function Washable:getDirtMultiplier(superFunc) |
167 | local multiplier = 1; |
168 | |
169 | if self:getIsOnField() then |
170 | multiplier = multiplier * self.fieldMultiplier; |
171 | end; |
172 | |
173 | if superFunc ~= nil then |
174 | multiplier = multiplier + superFunc(self); |
175 | end; |
176 | return multiplier; |
177 | end; |
178 | |
179 | function Washable:loadFromAttributesAndNodes(xmlFile, key, resetVehicles) |
180 | if Washable.getIntervalMultiplier() ~= 0 then |
181 | self:setDirtAmount(Utils.getNoNil(getXMLFloat(xmlFile, key.."#dirtAmount"), 0), true); |
182 | end |
183 | return BaseMission.VEHICLE_LOAD_OK; |
184 | end; |
185 | |
186 | function Washable:getSaveAttributesAndNodes(nodeIdent) |
187 | local attributes = 'dirtAmount="'.. tostring(self.dirtAmount) .. '"'; |
188 | return attributes, nil; |
189 | end; |
190 | |
191 | function Washable:addWashingTrigger(trigger) |
192 | table.insert(self.washingTriggers, trigger); |
193 | end; |
194 | |
195 | function Washable:removeWashingTrigger(trigger) |
196 | for i=1, table.getn(self.washingTriggers) do |
197 | if self.washingTriggers[i] == trigger then |
198 | table.remove(self.washingTriggers, i); |
199 | break; |
200 | end; |
201 | end; |
202 | end; |
203 | |
204 | function Washable.getIntervalMultiplier() |
205 | if g_settingsDirtInterval == 1 then |
206 | return 0; |
207 | elseif g_settingsDirtInterval == 2 then |
208 | return 0.25; |
209 | elseif g_settingsDirtInterval == 3 then |
210 | return 0.5; |
211 | elseif g_settingsDirtInterval == 4 then |
212 | return 1; |
213 | end; |
214 | end;
|
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de