23 | function LicensePlates.initSpecialization() |
24 | g_storeManager:addSpecType("licensePlate", "shopListAttributeIconLicensePlate", LicensePlates.loadSpecValuePlateText, LicensePlates.getSpecValuePlateText, "vehicle") |
25 | |
26 | local schema = Vehicle.xmlSchema |
27 | schema:setXMLSpecializationType("LicensePlates") |
28 | |
29 | schema:register(XMLValueType.STRING, "vehicle.licensePlates#defaultPlacement", "Defines the default placement index independent of map setting (NONE|BOTH|BACK_ONLY)", false) |
30 | schema:register(XMLValueType.NODE_INDEX, "vehicle.licensePlates.licensePlate(?)#node", "License plate node") |
31 | schema:register(XMLValueType.STRING, "vehicle.licensePlates.licensePlate(?)#preferedType", "Prefered license plate type to be placed if available") |
32 | schema:register(XMLValueType.VECTOR_4, "vehicle.licensePlates.licensePlate(?)#placementArea", "Defines the available area around the node (top, right, bottom, left) ('-' means unlimited)") |
33 | schema:register(XMLValueType.STRING, "vehicle.licensePlates.licensePlate(?)#position", "Position of license plate ('FRONT' or 'BACK')", "ANY") |
34 | schema:register(XMLValueType.BOOL, "vehicle.licensePlates.licensePlate(?)#frame", "License plate with frame of without frame", true) |
35 | |
36 | ObjectChangeUtil.registerObjectChangeXMLPaths(schema, "vehicle.licensePlates.licensePlate(?)") |
37 | |
38 | schema:setXMLSpecializationType() |
39 | |
40 | local schemaSavegame = Vehicle.xmlSchemaSavegame |
41 | schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).licensePlates#variation", "License plate variation", 1) |
42 | schemaSavegame:register(XMLValueType.STRING, "vehicles.vehicle(?).licensePlates#characters", "Characters string") |
43 | schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).licensePlates#colorIndex", "Selected color index", 1) |
44 | schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).licensePlates#placementIndex", "Selected placement index", 1) |
45 | end |
70 | function LicensePlates:onLoad(savegame) |
71 | local spec = self.spec_licensePlates |
72 | |
73 | spec.licensePlates = {} |
74 | local defaultPlacementName = self.xmlFile:getValue("vehicle.licensePlates#defaultPlacement") |
75 | if defaultPlacementName ~= nil then |
76 | spec.defaultPlacementIndex = LicensePlateManager.PLACEMENT_OPTION[defaultPlacementName:upper()] |
77 | end |
78 | |
79 | if g_licensePlateManager:getAreLicensePlatesAvailable() then |
80 | local i = 0 |
81 | while true do |
82 | local plateKey = string.format("vehicle.licensePlates.licensePlate(%d)", i) |
83 | if not self.xmlFile:hasProperty(plateKey) then |
84 | break |
85 | end |
86 | |
87 | local licensePlate = {} |
88 | |
89 | licensePlate.node = self.xmlFile:getValue(plateKey .. "#node", nil, self.components, self.i3dMappings) |
90 | if licensePlate.node ~= nil then |
91 | local preferedTypeStr = self.xmlFile:getValue(plateKey .. "#preferedType", "ELONGATED") |
92 | licensePlate.preferedType = LicensePlateManager.PLATE_TYPE[preferedTypeStr] |
93 | if licensePlate.preferedType ~= nil then |
94 | licensePlate.placementArea = {1, 1, 1, 1} |
95 | local placementAreaString = self.xmlFile:getString(plateKey .. "#placementArea") |
96 | if placementAreaString ~= nil then |
97 | local placementArea = string.split(placementAreaString, " ") |
98 | if #placementArea == 4 then |
99 | for j=1, 4 do |
100 | if placementArea[j] ~= "-" then |
101 | local numberValue = tonumber(placementArea[j]) |
102 | if numberValue == nil then |
103 | Logging.xmlWarning(self.xmlFile, "Invalid 4-vector '%s' for '%s'. '%s' is not a number!", placementAreaString, plateKey .. "#placementArea", placementArea[j]) |
104 | else |
105 | licensePlate.placementArea[j] = numberValue |
106 | end |
107 | end |
108 | end |
109 | else |
110 | Logging.xmlWarning(self.xmlFile, "Invalid 4-vector '%s' for '%s' ", placementAreaString, plateKey .. "#placementArea") |
111 | end |
112 | end |
113 | |
114 | local positionStr = self.xmlFile:getValue(plateKey .. "#position", "ANY") |
115 | licensePlate.position = LicensePlateManager.PLATE_POSITION[positionStr] or LicensePlateManager.PLATE_POSITION.ANY |
116 | |
117 | local includeFrame = self.xmlFile:getValue(plateKey .. "#frame", true) |
118 | |
119 | licensePlate.data = g_licensePlateManager:getLicensePlate(licensePlate.preferedType, includeFrame) |
120 | if licensePlate.data ~= nil then |
121 | link(licensePlate.node, licensePlate.data.node) |
122 | setTranslation(licensePlate.data.node, 0, 0, 0) |
123 | setRotation(licensePlate.data.node, 0, 0, 0) |
124 | setVisibility(licensePlate.data.node, false) |
125 | |
126 | local widthPos = licensePlate.data.rawWidth * 0.5 + licensePlate.data.widthOffsetLeft |
127 | local widthNeg = licensePlate.data.rawWidth * 0.5 + licensePlate.data.widthOffsetRight |
128 | local heightPos = licensePlate.data.rawHeight * 0.5 + licensePlate.data.heightOffsetTop |
129 | local heightNeg = licensePlate.data.rawHeight * 0.5 + licensePlate.data.heightOffsetBot |
130 | |
131 | local scaleFactorWidth = (licensePlate.placementArea[2] + licensePlate.placementArea[4]) / (widthPos + widthNeg) |
132 | local scaleFactorHeight = (licensePlate.placementArea[1] + licensePlate.placementArea[3]) / (heightPos + heightNeg) |
133 | local minFactor = MathUtil.clamp(math.min(scaleFactorWidth, scaleFactorHeight), 0, 1) |
134 | if minFactor < 1 then |
135 | setScale(licensePlate.data.node, minFactor, minFactor, minFactor) |
136 | |
137 | widthPos = widthPos * minFactor |
138 | widthNeg = widthNeg * minFactor |
139 | heightPos = heightPos * minFactor |
140 | heightNeg = heightNeg * minFactor |
141 | end |
142 | |
143 | local moveX, moveY = 0, 0 |
144 | moveX = moveX - math.max(widthPos - licensePlate.placementArea[2], 0) |
145 | moveX = moveX + math.max(widthNeg - licensePlate.placementArea[4], 0) |
146 | moveY = moveY - math.max(heightPos - licensePlate.placementArea[1], 0) |
147 | moveY = moveY + math.max(heightNeg - licensePlate.placementArea[3], 0) |
148 | setTranslation(licensePlate.data.node, moveX, moveY, 0) |
149 | |
150 | licensePlate.changeObjects = {} |
151 | ObjectChangeUtil.loadObjectChangeFromXML(self.xmlFile, plateKey, licensePlate.changeObjects, self.components, self) |
152 | |
153 | table.insert(spec.licensePlates, licensePlate) |
154 | end |
155 | else |
156 | Logging.xmlError(self.xmlFile, "Unknown preferedType '%s' for license plate '%s'", preferedTypeStr, plateKey) |
157 | end |
158 | end |
159 | |
160 | i = i + 1 |
161 | end |
162 | |
163 | if self:getHasLicensePlates() then |
164 | spec.licensePlateData = {variation=1, characters=nil, colorIndex=nil} |
165 | end |
166 | end |
167 | end |
171 | function LicensePlates:onPostLoad(savegame) |
172 | local spec = self.spec_licensePlates |
173 | |
174 | -- disable all object changes by default - will be enabled again if plate data is available |
175 | for i=1, #spec.licensePlates do |
176 | ObjectChangeUtil.setObjectChanges(spec.licensePlates[i].changeObjects, false, self, self.setMovingToolDirty) |
177 | end |
178 | |
179 | if savegame ~= nil and self:getHasLicensePlates() then |
180 | local variation = savegame.xmlFile:getValue(savegame.key .. ".licensePlates#variation", 1) |
181 | local characters = savegame.xmlFile:getValue(savegame.key .. ".licensePlates#characters") |
182 | local colorIndex = savegame.xmlFile:getValue(savegame.key .. ".licensePlates#colorIndex", 1) |
183 | local placementIndex = savegame.xmlFile:getValue(savegame.key .. ".licensePlates#placementIndex", 1) |
184 | |
185 | if variation ~= nil and characters ~= nil and colorIndex ~= nil and placementIndex ~= nil then |
186 | local characterTbl = {} |
187 | local characterLength = characters:len() |
188 | for i=1, characterLength do |
189 | table.insert(characterTbl, characters:sub(i, i)) |
190 | end |
191 | |
192 | spec.licensePlateData = {variation=variation, characters=characterTbl, colorIndex=colorIndex, placementIndex=placementIndex} |
193 | self:setLicensePlatesData(spec.licensePlateData) |
194 | end |
195 | end |
196 | end |
246 | function LicensePlates:setLicensePlatesData(licensePlateData) |
247 | local spec = self.spec_licensePlates |
248 | if licensePlateData ~= nil and licensePlateData.variation ~= nil and licensePlateData.characters ~= nil and licensePlateData.colorIndex ~= nil and licensePlateData.placementIndex ~= nil then |
249 | for i=1, #spec.licensePlates do |
250 | local licensePlate = spec.licensePlates[i] |
251 | |
252 | local allowLicensePlate = true |
253 | if licensePlateData.placementIndex == LicensePlateManager.PLACEMENT_OPTION.NONE then |
254 | allowLicensePlate = false |
255 | elseif licensePlateData.placementIndex == LicensePlateManager.PLACEMENT_OPTION.BACK_ONLY then |
256 | if licensePlate.position == LicensePlateManager.PLATE_POSITION.FRONT then |
257 | allowLicensePlate = false |
258 | end |
259 | end |
260 | |
261 | if allowLicensePlate then |
262 | licensePlate.data:updateData(licensePlateData.variation, licensePlate.position, table.concat(licensePlateData.characters, ""), true) |
263 | licensePlate.data:setColorIndex(licensePlateData.colorIndex) |
264 | |
265 | setVisibility(licensePlate.data.node, true) |
266 | else |
267 | setVisibility(licensePlate.data.node, false) |
268 | end |
269 | |
270 | ObjectChangeUtil.setObjectChanges(licensePlate.changeObjects, allowLicensePlate, self, self.setMovingToolDirty) |
271 | end |
272 | |
273 | spec.licensePlateData = licensePlateData |
274 | else |
275 | for i=1, #spec.licensePlates do |
276 | setVisibility(spec.licensePlates[i].data.node, false) |
277 | end |
278 | end |
279 | end |