Script v1.7.1.0
- AI
- Animals
- Contracts
- Debug
- Economy
- Effects
- Events
- Farms
- GUI
- Handtools
- I3d
- Materials
- Misc
- Objects
- Placeables
- Player
- Shop
- Sounds
- Specializations
- Triggers
- Utils
- Vehicles
- Weather
Engine v1.7.1.0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- XML
- general
Foundation Reference
StoreManager
DescriptionThis class handles all store categories and itemsParent
AbstractManagerFunctions
- addCategory
- addItem
- addSpecType
- getCategoryByName
- getItemByCustomEnvironment
- getItemByIndex
- getItemByXMLFilename
- getItems
- getSpecTypeByName
- getSpecTypes
- initDataStructures
- loadItem
- loadMapData
- new
- removeCategory
- removeItemByIndex
addCategory
DescriptionAdds a new store categoryDefinition
addCategory(string name, string title, string imageFilename, string baseDir)Arguments
string | name | category index name |
string | title | category title |
string | imageFilename | image |
string | baseDir | base directory |
boolean | true | if adding was successful else false |
127 | function StoreManager:addCategory(name, title, imageFilename, type, baseDir) |
128 | if name == nil or name == "" then |
129 | print("Warning: Could not register store category. Name is missing or empty!") |
130 | return false |
131 | end |
132 | if not ClassUtil.getIsValidIndexName(name) then |
133 | print("Warning: '"..tostring(name).."' is no valid name for a category!") |
134 | return false |
135 | end |
136 | if title == nil or title == "" then |
137 | print("Warning: Could not register store category. Title is missing or empty!") |
138 | return false |
139 | end |
140 | if imageFilename == nil or imageFilename == "" then |
141 | print("Warning: Could not register store category. Image is missing or empty!") |
142 | return false |
143 | end |
144 | if baseDir == nil then |
145 | print("Warning: Could not register store category. Basedirectory not defined!") |
146 | return false |
147 | end |
148 | |
149 | name = name:upper() |
150 | |
151 | if self.categories[name] == nil then |
152 | self.numOfCategories = self.numOfCategories + 1 |
153 | |
154 | local category = {} |
155 | category.name = name |
156 | category.title = title |
157 | category.image = Utils.getFilename(imageFilename, baseDir) |
158 | category.type = StoreManager.CATEGORY_TYPE[type] ~= nil and type or StoreManager.CATEGORY_TYPE.NONE |
159 | category.orderId = self.numOfCategories |
160 | |
161 | self.categories[name] = category |
162 | return true |
163 | end |
164 | return false |
165 | end |
addItem
DescriptionAdds a new store itemDefinition
addItem(table storeItem)Arguments
table | storeItem | the storeitem object |
boolean | wasSuccessfull | true if added else false |
254 | function StoreManager:addItem(storeItem) |
255 | if self.xmlFilenameToItem[storeItem.xmlFilenameLower] ~= nil then |
256 | return false |
257 | end |
258 | |
259 | table.insert(self.items, storeItem) |
260 | storeItem.id = #self.items |
261 | self.xmlFilenameToItem[storeItem.xmlFilenameLower] = storeItem |
262 | return true |
263 | end |
addSpecType
DescriptionAdds a new spec typeDefinition
addSpecType(string name, string profile, function loadFunc, function getValueFunc)Arguments
string | name | spec type index name |
string | profile | spec type gui profile |
function | loadFunc | the loading function pointer |
function | getValueFunc | the get value function pointer |
203 | function StoreManager:addSpecType(name, profile, loadFunc, getValueFunc) |
204 | if not ClassUtil.getIsValidIndexName(name) then |
205 | print("Warning: '"..tostring(name).."' is no valid name for a spec type!") |
206 | return |
207 | end |
208 | |
209 | name = name |
210 | |
211 | if self.nameToSpecType == nil then |
212 | printCallstack() |
213 | end |
214 | |
215 | if self.nameToSpecType[name] ~= nil then |
216 | print("Error: spec type name '" ..name.. "' is already in use!") |
217 | return |
218 | end |
219 | |
220 | local specType = {} |
221 | specType.name = name |
222 | specType.profile = profile |
223 | specType.loadFunc = loadFunc |
224 | specType.getValueFunc = getValueFunc |
225 | |
226 | self.nameToSpecType[name] = specType |
227 | table.insert(self.specTypes, specType) |
228 | end |
getCategoryByName
DescriptionGets a store category by nameDefinition
getCategoryByName(string name)Arguments
string | name | category index name |
table | category | the category object |
190 | function StoreManager:getCategoryByName(name) |
191 | if name ~= nil then |
192 | return self.categories[name:upper()] |
193 | end |
194 | return nil |
195 | end |
getItemByCustomEnvironment
DescriptionGets a store item xml filenameDefinition
getItemByCustomEnvironment(string xmlFilename)Arguments
string | xmlFilename | storeitem xml filename |
table | storeItem | the storeitem object |
315 | function StoreManager:getItemByCustomEnvironment(customEnvironment) |
316 | local items = {} |
317 | for _, item in ipairs(self.items) do |
318 | if item.customEnvironment == customEnvironment then |
319 | table.insert(items, item) |
320 | end |
321 | end |
322 | |
323 | return items |
324 | end |
getItemByIndex
DescriptionGets a store item by indexDefinition
getItemByIndex(integer index)Arguments
integer | index | store item index |
table | storeItem | the storeitem oject |
294 | function StoreManager:getItemByIndex(index) |
295 | if index ~= nil then |
296 | return self.items[index] |
297 | end |
298 | return nil |
299 | end |
getItemByXMLFilename
DescriptionGets a store item xml filenameDefinition
getItemByXMLFilename(string xmlFilename)Arguments
string | xmlFilename | storeitem xml filename |
table | storeItem | the storeitem object |
305 | function StoreManager:getItemByXMLFilename(xmlFilename) |
306 | if xmlFilename ~= nil then |
307 | return self.xmlFilenameToItem[xmlFilename:lower()] |
308 | end |
309 | end |
getItems
DescriptionGets all storeitemsDefinition
getItems()Return Values
table | items | a list of all store items |
286 | function StoreManager:getItems() |
287 | return self.items |
288 | end |
getSpecTypeByName
DescriptionGets a spec type by nameDefinition
getSpecTypeByName(string name)Arguments
string | name | spec type index name |
table | specType | the corresponding spectype |
241 | function StoreManager:getSpecTypeByName(name) |
242 | if not ClassUtil.getIsValidIndexName(name) then |
243 | print("Warning: '"..tostring(name).."' is no valid name for a spec type!") |
244 | return |
245 | end |
246 | |
247 | return self.nameToSpecType[name] |
248 | end |
getSpecTypes
DescriptionGets all spec typesDefinition
getSpecTypes()Return Values
table | specTypes | a list of spec types |
233 | function StoreManager:getSpecTypes() |
234 | return self.specTypes |
235 | end |
initDataStructures
DescriptionInitialize data structuresDefinition
initDataStructures()Code
33 | function StoreManager:initDataStructures() |
34 | self.numOfCategories = 0 |
35 | self.categories = {} |
36 | self.items = {} |
37 | self.xmlFilenameToItem = {} |
38 | self.modStoreItems = {} |
39 | |
40 | self.specTypes = {} |
41 | self.nameToSpecType = {} |
42 | end |
loadItem
DescriptionLoads a storeitem from xml fileDefinition
loadItem(string xmlFilename, string baseDir, string customEnvironment, boolean isMod, boolean isBundleItem, string dlcTitle)Arguments
string | xmlFilename | the storeitem xml filename |
string | baseDir | the base directory |
string | customEnvironment | a custom environment |
boolean | isMod | true if item is a mod, else false |
boolean | isBundleItem | true if item is bundleItem, else false |
string | dlcTitle | optional dlc title |
table | storeItem | the storeitem object |
339 | function StoreManager:loadItem(xmlFilename, baseDir, customEnvironment, isMod, isBundleItem, dlcTitle) |
340 | local xmlFilename = Utils.getFilename(xmlFilename, baseDir) |
341 | local xmlFile = loadXMLFile("storeItemXML", xmlFilename) |
342 | local baseXMLName = getXMLRootName(xmlFile) |
343 | local storeDataXMLName = baseXMLName..".storeData" |
344 | |
345 | if not hasXMLProperty(xmlFile, storeDataXMLName) then |
346 | g_logManager:xmlError(xmlFilename, "No storeData found. StoreItem will be ignored!") |
347 | delete(xmlFile) |
348 | return nil |
349 | end |
350 | |
351 | local isValid = true |
352 | local name = XMLUtil.getXMLI18NValue(xmlFile, storeDataXMLName, getXMLString, "name", nil, customEnvironment, true) |
353 | if name == nil then |
354 | g_logManager:xmlWarning(xmlFilename, "Name missing for storeitem. Ignoring store item!") |
355 | isValid = false |
356 | end |
357 | |
358 | local imageFilename = Utils.getNoNil(getXMLString(xmlFile, storeDataXMLName..".image"), "") |
359 | if imageFilename == "" then |
360 | g_logManager:xmlWarning(xmlFilename, "Image icon is missing for storeitem. Ignoring store item!") |
361 | isValid = false |
362 | end |
363 | |
364 | if not isValid then |
365 | delete(xmlFile) |
366 | return nil |
367 | end |
368 | |
369 | local storeItem = {} |
370 | storeItem.name = name |
371 | storeItem.xmlFilename = xmlFilename |
372 | storeItem.xmlFilenameLower = xmlFilename:lower() |
373 | storeItem.imageFilename = Utils.getFilename(imageFilename, baseDir) |
374 | storeItem.functions = StoreItemUtil.getFunctionsFromXML(xmlFile, storeDataXMLName, customEnvironment) |
375 | storeItem.specs = StoreItemUtil.getSpecsFromXML(self.specTypes, xmlFile, customEnvironment) |
376 | storeItem.brandIndex = StoreItemUtil.getBrandIndexFromXML(xmlFile, storeDataXMLName, xmlFilename) |
377 | storeItem.species = Utils.getNoNil(getXMLString(xmlFile, storeDataXMLName..".species"), "") |
378 | storeItem.canBeSold = Utils.getNoNil(getXMLBool(xmlFile, storeDataXMLName..".canBeSold"), true) |
379 | storeItem.showInStore = Utils.getNoNil(getXMLBool(xmlFile, storeDataXMLName..".showInStore"), not isBundleItem) |
380 | storeItem.isBundleItem = isBundleItem |
381 | storeItem.allowLeasing = Utils.getNoNil(getXMLBool(xmlFile, storeDataXMLName..".allowLeasing"), true) |
382 | storeItem.maxItemCount = getXMLInt(xmlFile, storeDataXMLName..".maxItemCount") |
383 | storeItem.rotation = Utils.getNoNilRad(getXMLFloat(xmlFile, storeDataXMLName..".rotation"), 0) |
384 | storeItem.shopTranslationOffset = StringUtil.getVectorNFromString(getXMLString(xmlFile, storeDataXMLName..".shopTranslationOffset"), 3) |
385 | storeItem.shopRotationOffset = StringUtil.getRadiansFromString(getXMLString(xmlFile, storeDataXMLName..".shopRotationOffset"), 3) |
386 | storeItem.shopHeight = Utils.getNoNil(getXMLFloat(xmlFile, storeDataXMLName..".shopHeight"), 0) |
387 | storeItem.financeCategory = getXMLString(xmlFile, storeDataXMLName..".financeCategory") |
388 | storeItem.shopFoldingState = Utils.getNoNil(getXMLBool(xmlFile, storeDataXMLName..".shopFoldingState"), 0) |
389 | storeItem.sharedVramUsage, storeItem.perInstanceVramUsage, storeItem.ignoreVramUsage = StoreItemUtil.getVRamUsageFromXML(xmlFile, storeDataXMLName) |
390 | storeItem.dlcTitle = dlcTitle |
391 | storeItem.isMod = isMod |
392 | storeItem.customEnvironment = customEnvironment |
393 | |
394 | local categoryName = getXMLString(xmlFile, storeDataXMLName..".category") |
395 | local category = self:getCategoryByName(categoryName) |
396 | if category == nil then |
397 | g_logManager:xmlWarning(xmlFilename, "Invalid category '%s' in store data! Using 'misc' instead!", tostring(categoryName)) |
398 | category = self:getCategoryByName("misc") |
399 | end |
400 | storeItem.categoryName = category.name |
401 | |
402 | storeItem.configurations = StoreItemUtil.getConfigurationsFromXML(xmlFile, baseXMLName, baseDir, customEnvironment, isMod, storeItem) |
403 | storeItem.subConfigurations = StoreItemUtil.getSubConfigurationsFromXML(storeItem.configurations) |
404 | storeItem.configurationSets = StoreItemUtil.getConfigurationSetsFromXML(storeItem, xmlFile, baseXMLName, baseDir, customEnvironment, isMod) |
405 | storeItem.price = Utils.getNoNil(getXMLFloat(xmlFile, storeDataXMLName..".price"), 0) |
406 | if storeItem.price < 0 then |
407 | g_logManager:xmlWarning(xmlFilename, "Price has to be greater than 0. Using default 10.000 instead!") |
408 | storeItem.price = 10000 |
409 | end |
410 | storeItem.dailyUpkeep = Utils.getNoNil(getXMLFloat(xmlFile, storeDataXMLName..".dailyUpkeep"), 0) |
411 | storeItem.runningLeasingFactor = Utils.getNoNil(getXMLFloat(xmlFile, storeDataXMLName..".runningLeasingFactor"), EconomyManager.DEFAULT_RUNNING_LEASING_FACTOR) |
412 | storeItem.lifetime = Utils.getNoNil(getXMLFloat(xmlFile, storeDataXMLName..".lifetime"), 600) |
413 | |
414 | |
415 | if hasXMLProperty(xmlFile, storeDataXMLName..".bundleElements") then |
416 | local bundleInfo = {bundleItems={}, attacherInfo={}} |
417 | local price = 0 |
418 | local lifetime = math.huge |
419 | local dailyUpkeep = 0 |
420 | local runningLeasingFactor = 0 |
421 | local i = 0 |
422 | while true do |
423 | local bundleKey = string.format(storeDataXMLName..".bundleElements.bundleElement(%d)", i) |
424 | if not hasXMLProperty(xmlFile, bundleKey) then |
425 | break |
426 | end |
427 | local bundleXmlFile = getXMLString(xmlFile, bundleKey..".xmlFilename") |
428 | local offset = StringUtil.getVectorNFromString(Utils.getNoNil(getXMLString(xmlFile, bundleKey..".offset"), "0 0 0"), 3) |
429 | local rotation = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, bundleKey..".yRotation"), 0)) |
430 | if bundleXmlFile ~= nil then |
431 | local completePath = Utils.getFilename(bundleXmlFile, baseDir) |
432 | local item = self:getItemByXMLFilename(completePath) |
433 | if item == nil then |
434 | item = self:loadItem(bundleXmlFile, baseDir, customEnvironment, isMod, true, dlcTitle) |
435 | end |
436 | if item ~= nil then |
437 | price = price + item.price |
438 | dailyUpkeep = dailyUpkeep + item.dailyUpkeep |
439 | runningLeasingFactor = runningLeasingFactor + item.runningLeasingFactor |
440 | lifetime = math.min(lifetime, item.lifetime) |
441 | table.insert(bundleInfo.bundleItems, {item=item, xmlFilename=item.xmlFilename, offset=offset, rotation=rotation, price=item.price}) |
442 | end |
443 | end |
444 | i = i + 1 |
445 | end |
446 | local i = 0 |
447 | while true do |
448 | local attachKey = string.format(storeDataXMLName..".attacherInfo.attach(%d)", i) |
449 | if not hasXMLProperty(xmlFile, attachKey) then |
450 | break |
451 | end |
452 | local bundleElement0 = getXMLInt(xmlFile, attachKey.."#bundleElement0") |
453 | local bundleElement1 = getXMLInt(xmlFile, attachKey.."#bundleElement1") |
454 | local attacherJointIndex = getXMLInt(xmlFile, attachKey.."#attacherJointIndex") |
455 | local inputAttacherJointIndex = getXMLInt(xmlFile, attachKey.."#inputAttacherJointIndex") |
456 | if bundleElement0 ~= nil and bundleElement1 ~= nil and attacherJointIndex ~= nil and inputAttacherJointIndex ~= nil then |
457 | table.insert(bundleInfo.attacherInfo, {bundleElement0=bundleElement0, bundleElement1=bundleElement1, attacherJointIndex=attacherJointIndex, inputAttacherJointIndex=inputAttacherJointIndex}) |
458 | end |
459 | i = i + 1 |
460 | end |
461 | |
462 | storeItem.price = price |
463 | storeItem.dailyUpkeep = dailyUpkeep |
464 | storeItem.runningLeasingFactor = runningLeasingFactor |
465 | storeItem.lifetime = lifetime |
466 | storeItem.bundleInfo = bundleInfo |
467 | end |
468 | |
469 | self:addItem(storeItem) |
470 | |
471 | delete(xmlFile) |
472 | |
473 | return storeItem |
474 | end |
loadMapData
DescriptionLoad manager data on map loadDefinition
loadMapData()Return Values
boolean | true | if loading was successful else false |
47 | function StoreManager:loadMapData(xmlFile, missionInfo, baseDirectory) |
48 | StoreManager:superClass().loadMapData(self) |
49 | |
50 | -- local all store categories |
51 | local categoryXMLFile = loadXMLFile("storeCategoriesXML", "dataS/storeCategories.xml") |
52 | local i = 0 |
53 | while true do |
54 | local baseXMLName = string.format("categories.category(%d)", i) |
55 | |
56 | if not hasXMLProperty(categoryXMLFile, baseXMLName) then |
57 | break |
58 | end |
59 | local name = getXMLString(categoryXMLFile, baseXMLName .. "#name") |
60 | local title = getXMLString(categoryXMLFile, baseXMLName .. "#title") |
61 | local imageFilename = getXMLString(categoryXMLFile, baseXMLName .. "#image") |
62 | local type = getXMLString(categoryXMLFile, baseXMLName .. "#type") |
63 | |
64 | if title ~= nil and title:sub(1, 6) == "$l10n_" then |
65 | title = g_i18n:getText(title:sub(7)) |
66 | end |
67 | |
68 | self:addCategory(name, title, imageFilename, type, "") |
69 | |
70 | i = i + 1 |
71 | end |
72 | delete(categoryXMLFile) |
73 | |
74 | -- now load all storeitems |
75 | |
76 | local storeItemsFilename = "dataS/storeItems.xml" |
77 | if g_isPresentationVersionSpecialStore then |
78 | storeItemsFilename = g_isPresentationVersionSpecialStorePath |
79 | end |
80 | |
81 | self:loadItemsFromXML(storeItemsFilename) |
82 | |
83 | if xmlFile ~= nil then |
84 | local mapStoreItemsFilename = getXMLString(xmlFile, "map.storeItems#filename") |
85 | if mapStoreItemsFilename ~= nil then |
86 | mapStoreItemsFilename = Utils.getFilename(mapStoreItemsFilename, baseDirectory) |
87 | self:loadItemsFromXML(mapStoreItemsFilename) |
88 | end |
89 | end |
90 | |
91 | for _, item in ipairs(self.modStoreItems) do |
92 | g_deferredLoadingManager:addSubtask(function() |
93 | self:loadItem(item.xmlFilename, item.baseDir, item.customEnvironment, item.isMod, item.isBundleItem, item.dlcTitle) |
94 | end) |
95 | end |
96 | |
97 | return true |
98 | end |
new
DescriptionCreating managerDefinition
new()Return Values
table | instance | instance of object |
25 | function StoreManager:new(customMt) |
26 | local self = AbstractManager:new(customMt or StoreManager_mt) |
27 | |
28 | return self |
29 | end |
removeCategory
DescriptionRemoves a store categoryDefinition
removeCategory(string name)Arguments
string | name | category index name |
170 | function StoreManager:removeCategory(name) |
171 | if not ClassUtil.getIsValidIndexName(name) then |
172 | print("Warning: '"..tostring(name).."' is no valid name for a category!") |
173 | return |
174 | end |
175 | |
176 | name = name:upper() |
177 | |
178 | for _, item in pairs(self.items) do |
179 | if item.category == name then |
180 | item.category = "MISC" |
181 | end |
182 | end |
183 | self.categories[name] = nil |
184 | end |
removeItemByIndex
DescriptionRemoves a storeitem by indexDefinition
removeItemByIndex(integer index)Arguments
integer | index | storeitem index |
268 | function StoreManager:removeItemByIndex(index) |
269 | local item = self.items[index] |
270 | if item ~= nil then |
271 | self.xmlFilenameToItem[item.xmlFilenameLower] = nil |
272 | |
273 | -- item.id must always match the index in the arry, thus swap the last to the removed position and reduce size |
274 | local numItems = table.getn(self.items) |
275 | if index < numItems then |
276 | self.items[index] = self.items[numItems] |
277 | self.items[index].id = index |
278 | end |
279 | table.remove(self.items, numItems) |
280 | end |
281 | end |