LUADOC - Farming Simulator 22

FarmlandManager

Description
This class handles all basic functionality for land ownership
Parent
AbstractManager
Functions

addStateChangeListener

Description
Adds a farmland state change listener
Definition
addStateChangeListener(table listener)
Arguments
tablelistenerstate listener
Code
438function FarmlandManager:addStateChangeListener(listener)
439 if listener ~= nil and listener.onFarmlandStateChanged ~= nil then
440 self.stateChangeListener[listener] = listener
441 end
442end

consoleCommandBuyAllFarmlands

Description
Definition
consoleCommandBuyAllFarmlands()
Code
475function FarmlandManager:consoleCommandBuyAllFarmlands()
476 if (g_currentMission:getIsServer() or g_currentMission.isMasterUser) and g_currentMission:getIsClient() then
477 local farmId = g_currentMission.player.farmId
478
479 for k, _ in pairs(g_farmlandManager:getFarmlands()) do
480 g_client:getServerConnection():sendEvent(FarmlandStateEvent.new(k, farmId, 0))
481 end
482 return "Bought all farmlands"
483 else
484 return "Command not allowed"
485 end
486end

consoleCommandBuyFarmland

Description
Definition
consoleCommandBuyFarmland()
Code
455function FarmlandManager:consoleCommandBuyFarmland(farmlandId)
456 if (g_currentMission:getIsServer() or g_currentMission.isMasterUser) and g_currentMission:getIsClient() then
457 farmlandId = tonumber(farmlandId)
458 if farmlandId == nil then
459 return "Invalid farmland id. Use gsFarmlandBuy <farmlandId>"
460 end
461
462 local farmId = g_currentMission.player.farmId
463
464 -- send buy request
465 g_client:getServerConnection():sendEvent(FarmlandStateEvent.new(farmlandId, farmId, 0))
466
467 return "Bought farmland "..farmlandId
468 else
469 return "Command not allowed"
470 end
471end

consoleCommandSellAllFarmlands

Description
Definition
consoleCommandSellAllFarmlands()
Code
508function FarmlandManager:consoleCommandSellAllFarmlands()
509 if (g_currentMission:getIsServer() or g_currentMission.isMasterUser) and g_currentMission:getIsClient() then
510 for k, _ in pairs(g_farmlandManager:getFarmlands()) do
511 g_client:getServerConnection():sendEvent(FarmlandStateEvent.new(k, FarmlandManager.NO_OWNER_FARM_ID, 0))
512 end
513 return "Sold all farmlands"
514 else
515 return "Command not allowed"
516 end
517end

consoleCommandSellFarmland

Description
Definition
consoleCommandSellFarmland()
Code
490function FarmlandManager:consoleCommandSellFarmland(farmlandId)
491 if (g_currentMission:getIsServer() or g_currentMission.isMasterUser) and g_currentMission:getIsClient() then
492 farmlandId = tonumber(farmlandId)
493 if farmlandId == nil then
494 return "Invalid farmland id. Use gsFarmlandSell <farmlandId>"
495 end
496
497 -- send sell request
498 g_client:getServerConnection():sendEvent(FarmlandStateEvent.new(farmlandId, FarmlandManager.NO_OWNER_FARM_ID, 0))
499
500 return "Sold farmland "..farmlandId
501 else
502 return "Command not allowed"
503 end
504end

consoleCommandShowFarmlands

Description
Definition
consoleCommandShowFarmlands()
Code
521function FarmlandManager:consoleCommandShowFarmlands()
522 if not g_currentMission:getHasDrawable(self) then
523 g_currentMission:addDrawable(self)
524 return "showFarmlands = true\nUse F5 to enter debug mode for enabling overlay"
525 else
526 g_currentMission:removeDrawable(self)
527 return "showFarmlands = false"
528 end
529end

convertWorldToLocalPosition

Description
Converts world to local position
Definition
convertWorldToLocalPosition(float worldPosX, float worldPosZ)
Arguments
floatworldPosXworld position x
floatworldPosZworld position z
Return Values
floatlocalPosXlocal position x
floatlocalPosZlocal position z
Code
419function FarmlandManager:convertWorldToLocalPosition(worldPosX, worldPosZ)
420 local terrainSize = g_currentMission.terrainSize
421 return math.floor(self.localMapWidth * (worldPosX+terrainSize*0.5) / terrainSize),
422 math.floor(self.localMapHeight * (worldPosZ+terrainSize*0.5) / terrainSize)
423end

delete

Description
Deletes farm land manager
Definition
delete()
Code
255function FarmlandManager:delete()
256end

farmDestroyed

Description
Definition
farmDestroyed()
Code
427function FarmlandManager:farmDestroyed(farmId)
428 for _, farmland in pairs(self:getFarmlands()) do
429 if self:getFarmlandOwner(farmland.id) == farmId then
430 self:setLandOwnership(farmland.id, FarmlandManager.NO_OWNER_FARM_ID)
431 end
432 end
433end

getCanAccessLandAtWorldPosition

Description
Checks if farm can access the given world position
Definition
getCanAccessLandAtWorldPosition(integer farmId, float worldPosX, float worldPosZ)
Arguments
integerfarmIdfarm id
floatworldPosXworld position x
floatworldPosZworld position z
Return Values
booleancanAccesstrue if farm can access the land
Code
285function FarmlandManager:getCanAccessLandAtWorldPosition(farmId, worldPosX, worldPosZ)
286 if farmId == FarmlandManager.NO_OWNER_FARM_ID or farmId == nil then
287 return false
288 end
289
290 local farmlandId = self:getFarmlandIdAtWorldPosition(worldPosX, worldPosZ)
291 local ownerFarmId = self.farmlandMapping[farmlandId]
292 if ownerFarmId == farmId then
293 return true
294 end
295
296 return g_currentMission.accessHandler:canFarmAccessOtherId(farmId, ownerFarmId)
297end

getFarmlandAtWorldPosition

Description
Definition
getFarmlandAtWorldPosition()
Code
324function FarmlandManager:getFarmlandAtWorldPosition(worldPosX, worldPosZ)
325 local farmlandId = self:getFarmlandIdAtWorldPosition(worldPosX, worldPosZ)
326 return self.farmlands[farmlandId]
327end

getFarmlandById

Description
Gets farmland by id
Definition
getFarmlandById(integer farmlandId)
Arguments
integerfarmlandIdfarmland id
Return Values
tablefarmlandfarmland object
Code
382function FarmlandManager:getFarmlandById(farmlandId)
383 return self.farmlands[farmlandId]
384end

getFarmlandIdAtWorldPosition

Description
Gets farmland id at given world position
Definition
getFarmlandIdAtWorldPosition(float worldPosX, float worldPosZ)
Arguments
floatworldPosXworld position x
floatworldPosZworld position z
Return Values
integerfarmlandIdfarmland id. if 0, world position is no valid/buyable farmland
Code
317function FarmlandManager:getFarmlandIdAtWorldPosition(worldPosX, worldPosZ)
318 local localPosX, localPosZ = self:convertWorldToLocalPosition(worldPosX, worldPosZ)
319 return getBitVectorMapPoint(self.localMap, localPosX, localPosZ, 0, self.numberOfBits)
320end

getFarmlandOwner

Description
Gets farmland owner
Definition
getFarmlandOwner(integer farmlandId)
Arguments
integerfarmlandIdfarmland id
Return Values
integerfarmIdid of farm. Returns 0 if land is not owned by anyone
Code
303function FarmlandManager:getFarmlandOwner(farmlandId)
304--#debug assert(type(farmlandId ~= "table")) -- ensure farmland id and not farmland itself it given
305 if farmlandId == nil or self.farmlandMapping[farmlandId] == nil then
306 return FarmlandManager.NO_OWNER_FARM_ID
307 end
308
309 return self.farmlandMapping[farmlandId]
310end

getFarmlands

Description
Gets all farmlands
Definition
getFarmlands()
Return Values
tablefarmlandsall available farmlands
Code
389function FarmlandManager:getFarmlands()
390 return self.farmlands
391end

getIsOwnedByFarmAtWorldPosition

Description
Checks if farm owns given world position
Definition
getIsOwnedByFarmAtWorldPosition(integer farmId, float worldPosX, float worldPosZ)
Arguments
integerfarmIdfarm id
floatworldPosXworld position x
floatworldPosZworld position z
Return Values
booleanisOwnedtrue if farm owns world position point, else false
Code
271function FarmlandManager:getIsOwnedByFarmAtWorldPosition(farmId, worldPosX, worldPosZ)
272 if farmId == FarmlandManager.NO_OWNER_FARM_ID or farmId == nil then
273 return false
274 end
275 local farmlandId = self:getFarmlandIdAtWorldPosition(worldPosX, worldPosZ)
276 return self.farmlandMapping[farmlandId] == farmId
277end

getIsValidFarmlandId

Description
Checks if given farmland-id is valid
Definition
getIsValidFarmlandId(integer farmlandId)
Arguments
integerfarmlandIdfarmland id
Return Values
booleanisValidtrue if id is valid, else false
Code
340function FarmlandManager:getIsValidFarmlandId(farmlandId)
341 if farmlandId == nil or farmlandId == 0 or farmlandId < 0 then
342 return false
343 end
344 if self:getFarmlandById(farmlandId) == nil then
345 return false
346 end
347 return true
348end

getLocalMap

Description
Gets farmland bit vector handle
Definition
getLocalMap()
Return Values
integermapHandleid of bitvector
Code
261function FarmlandManager:getLocalMap()
262 return self.localMap
263end

getOwnedFarmlandIdsByFarmId

Description
Gets list of owned farmland ids for given farm
Definition
getOwnedFarmlandIdsByFarmId(integer farmId)
Arguments
integerfarmIdfarm id
Return Values
farmlandIdstablelist of farmland ids owned by given farm id
Code
403function FarmlandManager:getOwnedFarmlandIdsByFarmId(id)
404 local farmlandIds = {}
405 for farmlandId, farmId in pairs(self.farmlandMapping) do
406 if farmId == id then
407 table.insert(farmlandIds, farmlandId)
408 end
409 end
410 return farmlandIds
411end

getOwnerIdAtWorldPosition

Description
Definition
getOwnerIdAtWorldPosition()
Code
331function FarmlandManager:getOwnerIdAtWorldPosition(worldPosX, worldPosZ)
332 local farmlandId = self:getFarmlandIdAtWorldPosition(worldPosX, worldPosZ)
333 return self:getFarmlandOwner(farmlandId)
334end

getPricePerHa

Description
Definition
getPricePerHa()
Code
395function FarmlandManager:getPricePerHa()
396 return self.pricePerHa
397end

initDataStructures

Description
Initialize data structures
Definition
initDataStructures()
Code
27function FarmlandManager:initDataStructures()
28 self.farmlands = {}
29 self.sortedFarmlandIds = {}
30 -- mapping table farmland id to farm id
31 self.farmlandMapping = {}
32 self.localMap = nil
33 self.localMapWidth = 0
34 self.localMapHeight = 0
35 self.numberOfBits = 8
36 self.stateChangeListener = {}
37end

loadFarmlandData

Description
Load data on map load
Definition
loadFarmlandData()
Return Values
booleantrueif loading was successful else false
Code
51function FarmlandManager:loadFarmlandData(xmlFile)
52 local filename = Utils.getFilename(getXMLString(xmlFile, "map.farmlands#densityMapFilename"), g_currentMission.baseDirectory)
53
54 -- number of channels for farmland bit vector
55 self.numberOfBits = Utils.getNoNil(getXMLInt(xmlFile, "map.farmlands#numChannels"), 8)
56 self.pricePerHa = Utils.getNoNil(getXMLFloat(xmlFile, "map.farmlands#pricePerHa"), 60000)
57
58 FarmlandManager.NOT_BUYABLE_FARM_ID = 2^self.numberOfBits-1
59
60 -- load a bitvector
61 self.localMap = createBitVectorMap("FarmlandMap")
62 local success = loadBitVectorMapFromFile(self.localMap, filename, self.numberOfBits)
63 if not success then
64 Logging.xmlWarning(xmlFile, "Loading farmland file '%s' failed!", filename)
65 return false
66 end
67
68 self.localMapWidth, self.localMapHeight = getBitVectorMapSize(self.localMap)
69
70 local farmlandSizeMapping = {}
71 local farmlandCenterData = {}
72 local numOfFarmlands = 0
73 local maxFarmlandId = 0
74 local missingFarmlandDefinitions = false
75
76 for x = 0, self.localMapWidth - 1 do
77 for y = 0, self.localMapHeight - 1 do
78 local value = getBitVectorMapPoint(self.localMap, x, y, 0, self.numberOfBits)
79
80 if value > 0 then
81 if self.farmlandMapping[value] == nil then
82 farmlandSizeMapping[value] = 0
83 farmlandCenterData[value] = {sumPosX=0, sumPosZ=0}
84 self.farmlandMapping[value] = FarmlandManager.NO_OWNER_FARM_ID
85 numOfFarmlands = numOfFarmlands + 1
86 maxFarmlandId = math.max(value, maxFarmlandId)
87 end
88
89 farmlandSizeMapping[value] = farmlandSizeMapping[value] + 1
90 farmlandCenterData[value].sumPosX = farmlandCenterData[value].sumPosX + (x-0.5)
91 farmlandCenterData[value].sumPosZ = farmlandCenterData[value].sumPosZ + (y-0.5)
92 else
93 missingFarmlandDefinitions = true
94 end
95 end
96 end
97
98 if missingFarmlandDefinitions then
99 Logging.xmlWarning(xmlFile, "Farmland-Id was not set for all pixels in farmland-infoLayer!")
100 end
101
102 local isNewSavegame = not g_currentMission.missionInfo.isValid
103
104 local i = 0
105 while true do
106 local key = string.format("map.farmlands.farmland(%d)", i)
107 if not hasXMLProperty(xmlFile, key) then
108 break
109 end
110
111 local farmland = Farmland.new()
112 if farmland:load(xmlFile, key) and self.farmlands[farmland.id] == nil and self.farmlandMapping[farmland.id] ~= nil then
113 self.farmlands[farmland.id] = farmland
114 table.insert(self.sortedFarmlandIds, farmland.id)
115
116 -- If default should be owned...
117 local shouldAddDefaults = isNewSavegame and g_currentMission.missionInfo.hasInitiallyOwnedFarmlands and not g_currentMission.missionDynamicInfo.isMultiplayer
118 -- ... then set only default farmlands to owned
119 if shouldAddDefaults and g_currentMission:getIsServer() and farmland.defaultFarmProperty then
120 self:setLandOwnership(farmland.id, FarmManager.SINGLEPLAYER_FARM_ID)
121 end
122 else
123 if self.farmlandMapping[farmland.id] == nil then
124 Logging.xmlError(xmlFile, "Farmland-Id " .. tostring(farmland.id) .. " not defined in farmland ownage file '"..filename.."'. Skipping farmland definition!")
125 end
126 if self.farmlands[farmland.id] ~= nil then
127 Logging.xmlError(xmlFile, "Farmland-id '"..tostring(farmland.id).."' already exists! Ignore it!")
128 end
129 farmland:delete()
130 end
131
132 i = i + 1
133 end
134
135 for index, _ in pairs(self.farmlandMapping) do
136 if index ~= FarmlandManager.NOT_BUYABLE_FARM_ID and self.farmlands[index] == nil then
137 Logging.xmlError(xmlFile, "Farmland-Id " .. tostring(index) .. " not defined in farmland xml file!")
138 end
139 end
140
141 local transformFactor = g_currentMission.terrainSize / self.localMapWidth
142 local pixelToSqm = transformFactor*transformFactor
143
144 for id, farmland in pairs(self.farmlands) do
145 local ha = MathUtil.areaToHa(farmlandSizeMapping[id], pixelToSqm)
146 farmland:setArea(ha)
147
148 local posX = ((farmlandCenterData[id].sumPosX / farmlandSizeMapping[id]) - self.localMapWidth*0.5) * transformFactor
149 local posZ = ((farmlandCenterData[id].sumPosZ / farmlandSizeMapping[id]) - self.localMapHeight*0.5) * transformFactor
150 self.farmlands[id]:setFarmlandIndicatorPosition(posX, posZ)
151 end
152
153 g_messageCenter:subscribe(MessageType.FARM_DELETED, self.farmDestroyed, self)
154
155 if g_currentMission:getIsServer() then
156 if g_addCheatCommands then
157 -- master user only cheats (will be added in setMasterUserLocal too)
158 addConsoleCommand("gsFarmlandBuy", "Buys farmland with given id", "consoleCommandBuyFarmland", self)
159 addConsoleCommand("gsFarmlandBuyAll", "Buys all farmlands", "consoleCommandBuyAllFarmlands", self)
160 addConsoleCommand("gsFarmlandSell", "Sells farmland with given id", "consoleCommandSellFarmland", self)
161 addConsoleCommand("gsFarmlandSellAll", "Sells all farmlands", "consoleCommandSellAllFarmlands", self)
162 addConsoleCommand("gsFarmlandShow", "Show farmlands", "consoleCommandShowFarmlands", self)
163 end
164 end
165
166 return true
167end

loadFromXMLFile

Description
Load farmland ownage data from xml savegame file
Definition
loadFromXMLFile(string filename)
Arguments
stringfilenamexml filename
Code
221function FarmlandManager:loadFromXMLFile(xmlFilename)
222 if xmlFilename == nil then
223 return false
224 end
225
226 local xmlFile = loadXMLFile("farmlandXML", xmlFilename)
227 if xmlFile == 0 then
228 return false
229 end
230
231 local farmlandCounter = 0
232 while true do
233 local key = string.format("farmlands.farmland(%d)", farmlandCounter)
234 local farmlandId = getXMLInt(xmlFile, key .. "#id")
235 if farmlandId == nil then
236 break
237 end
238 local farmId = getXMLInt(xmlFile, key .. "#farmId")
239 if farmId > FarmlandManager.NO_OWNER_FARM_ID then
240 self:setLandOwnership(farmlandId, farmId)
241 end
242
243 farmlandCounter = farmlandCounter + 1
244 end
245
246 delete(xmlFile)
247
248 g_farmManager:mergeFarmlandsForSingleplayer()
249
250 return true
251end

loadMapData

Description
Load data on map load
Definition
loadMapData()
Return Values
booleantrueif loading was successful else false
Code
43function FarmlandManager:loadMapData(xmlFile)
44 FarmlandManager:superClass().loadMapData(self)
45 return XMLUtil.loadDataFromMapXML(xmlFile, "farmlands", g_currentMission.baseDirectory, self, self.loadFarmlandData)
46end

new

Description
Creating manager
Definition
new()
Return Values
tableinstanceinstance of object
Code
20function FarmlandManager.new(customMt)
21 local self = AbstractManager.new(customMt or FarmlandManager_mt)
22 return self
23end

removeStateChangeListener

Description
Removes a farmland state change listener
Definition
removeStateChangeListener(table listener)
Arguments
tablelistenerstate listener
Code
447function FarmlandManager:removeStateChangeListener(listener)
448 if listener ~= nil then
449 self.stateChangeListener[listener] = nil
450 end
451end

saveToXMLFile

Description
Write farmland ownage data to savegame file
Definition
saveToXMLFile(string xmlFilename)
Arguments
stringxmlFilenamefile path
Return Values
booleantrueif loading was successful else false
Code
197function FarmlandManager:saveToXMLFile(xmlFilename)
198 -- save farmland to xml
199 local xmlFile = createXMLFile("farmlandsXML", xmlFilename, "farmlands")
200 if xmlFile ~= nil then
201 local index = 0
202 for farmlandId, farmId in pairs(self.farmlandMapping) do
203 local farmlandKey = string.format("farmlands.farmland(%d)", index)
204 setXMLInt(xmlFile, farmlandKey.."#id", farmlandId)
205 setXMLInt(xmlFile, farmlandKey.."#farmId", Utils.getNoNil(farmId, FarmlandManager.NO_OWNER_FARM_ID))
206 index = index + 1
207 end
208
209 saveXMLFile(xmlFile)
210 delete(xmlFile)
211
212 return true
213 end
214
215 return false
216end

setLandOwnership

Description
Sets farm land ownership
Definition
setLandOwnership(integer farmlandId, integer farmId)
Arguments
integerfarmlandIdfarm land id
integerfarmIdfarm id. set farmid to 0 to sell farm land
Code
354function FarmlandManager:setLandOwnership(farmlandId, farmId)
355 if not self:getIsValidFarmlandId(farmlandId) then
356 return false
357 end
358 if farmId == nil or farmId < FarmlandManager.NO_OWNER_FARM_ID or farmId == FarmlandManager.NOT_BUYABLE_FARM_ID then
359 return false
360 end
361
362 local farmland = self:getFarmlandById(farmlandId)
363 if farmland == nil then
364 Logging.warning("Farmland id %d not defined in map!", farmlandId)
365 return false
366 end
367
368 self.farmlandMapping[farmlandId] = farmId
369 farmland.isOwned = farmId ~= FarmlandManager.NO_OWNER_FARM_ID
370
371 for _, listener in pairs(self.stateChangeListener) do
372 listener:onFarmlandStateChanged(farmlandId, farmId)
373 end
374
375 return true
376end

unloadMapData

Description
Unload data on mission delete
Definition
unloadMapData()
Code
171function FarmlandManager:unloadMapData()
172 removeConsoleCommand("gsFarmlandBuy")
173 removeConsoleCommand("gsFarmlandBuyAll")
174 removeConsoleCommand("gsFarmlandSell")
175 removeConsoleCommand("gsFarmlandSellAll")
176 removeConsoleCommand("gsFarmlandShow")
177
178 g_messageCenter:unsubscribeAll(self)
179
180 if self.localMap ~= nil then
181 delete(self.localMap)
182 self.localMap = nil
183 end
184 if (self.farmlands ~= nil) then
185 for _, farmland in pairs(self.farmlands) do
186 farmland:delete()
187 end
188 end
189
190 FarmlandManager:superClass().unloadMapData(self)
191end