LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

PlaceableHusbandryFood

Description
Specialization for placeables
Functions

addFood

Description
Definition
addFood()
Code
518function PlaceableHusbandryFood:addFood(farmId, deltaFillLevel, fillTypeIndex, fillPositionData, toolType, extraAttributes)
519 local spec = self.spec_husbandryFood
520 if spec.supportedFillTypes[fillTypeIndex] == nil then
521 return 0
522 end
523
524 local mixture = g_currentMission.animalFoodSystem:getMixtureByFillType(fillTypeIndex)
525 if mixture ~= nil then
526 local filled = 0
527 local maxDelta = math.min(deltaFillLevel, self:getFreeFoodCapacity(fillTypeIndex))
528 for _, ingredient in ipairs(mixture.ingredients) do
529 local delta = maxDelta * ingredient.weight
530 local ingredientFillType = ingredient.fillTypes[1]
531 local filledDelta = self:addFood(farmId, delta, ingredientFillType, fillPositionData, toolType, extraAttributes)
532 filled = filled + filledDelta
533 end
534
535 if filled > 0 then
536 self:updateFillPlanes(fillTypeIndex)
537 end
538
539 return filled
540 end
541
542 local freeCapacity = self:getFreeFoodCapacity(fillTypeIndex)
543 if freeCapacity == 0 then
544 return 0
545 end
546
547 deltaFillLevel = math.min(freeCapacity, deltaFillLevel)
548
549 if spec.dynamicFoodPlane ~= nil then
550 if fillPositionData ~= nil then
551 local data = fillPositionData
552
553 local x0, y0, z0 = getWorldTranslation(data.node)
554 local d1x, d1y, d1z = localDirectionToWorld(data.node, data.width, 0, 0)
555 local d2x, d2y, d2z = localDirectionToWorld(data.node, 0, 0, data.length)
556
557 if VehicleDebug.state == VehicleDebug.DEBUG then
558 drawDebugLine( x0,y0,z0, 1,0,0, x0+d1x, y0+d1y, z0+d1z, 1,0,0 )
559 drawDebugLine( x0,y0,z0, 0,0,1, x0+d2x, y0+d2y, z0+d2z, 0,0,1 )
560 drawDebugPoint( x0,y0,z0, 1,1,1,1 )
561 drawDebugPoint( x0+d1x, y0+d1y, z0+d1z, 1,0,0,1 )
562 drawDebugPoint( x0+d2x, y0+d2y, z0+d2z, 0,0,1,1 )
563 end
564
565 x0 = x0 - (d1x + d2x) / 2
566 y0 = y0 - (d1y + d2y) / 2
567 z0 = z0 - (d1z + d2z) / 2
568 fillPlaneAdd(spec.dynamicFoodPlane, deltaFillLevel, x0, y0, z0, d1x, d1y, d1z, d2x, d2y, d2z)
569
570 if self.isServer and math.abs(x0-spec.lastPositionInfoSent[1]) > FillVolume.SEND_PRECISION or math.abs(z0-spec.lastPositionInfoSent[2]) > FillVolume.SEND_PRECISION then
571 spec.lastPositionInfoSent[1] = x0
572 spec.lastPositionInfoSent[2] = z0
573
574 self:raiseDirtyFlags(spec.dirtyFlagPosition)
575 end
576 else
577 local x,y,z = localToWorld(spec.dynamicFoodPlane, 0,0,0)
578 local d1x,d1y,d1z = localDirectionToWorld(spec.dynamicFoodPlane, 0.1, 0, 0)
579 local d2x,d2y,d2z = localDirectionToWorld(spec.dynamicFoodPlane, 0, 0, 0.1)
580
581 if not self.isServer then
582 if spec.lastPositionInfo[1] ~= 0 and spec.lastPositionInfo[2] ~= 0 then
583 x, y, z = localToWorld(spec.dynamicFoodPlane, spec.lastPositionInfo[1], 0, spec.lastPositionInfo[2])
584 end
585 end
586
587 local steps = MathUtil.clamp(math.floor(deltaFillLevel/400), 1, 25)
588 for _=1, steps do
589 fillPlaneAdd(spec.dynamicFoodPlane, deltaFillLevel/steps, x,y,z, d1x,d1y,d1z, d2x,d2y,d2z)
590 end
591 end
592 end
593
594 if self.isServer then
595 self:raiseDirtyFlags(spec.dirtyFlagFillLevel)
596 end
597
598 spec.fillLevels[fillTypeIndex] = spec.fillLevels[fillTypeIndex] + deltaFillLevel
599
600 self:updateFillPlanes(fillTypeIndex)
601 self:updateFoodPlaces()
602
603 return deltaFillLevel
604end

collectPickObjects

Description
Definition
collectPickObjects()
Code
452function PlaceableHusbandryFood:collectPickObjects(superFunc, node)
453 local spec = self.spec_husbandryFood
454 if spec.feedingTrough ~= nil and node == spec.feedingTrough.exactFillRootNode then
455 return
456 end
457
458 superFunc(self, node)
459end

getAnimalDescription

Description
Definition
getAnimalDescription()
Code
667function PlaceableHusbandryFood:getAnimalDescription(superFunc, cluster)
668 local text = superFunc(self, cluster)
669
670 return text .. " " .. g_i18n:getText("animal_descriptionPercentage")
671end

getFoodCapacity

Description
Definition
getFoodCapacity()
Code
501function PlaceableHusbandryFood:getFoodCapacity()
502 return self.spec_husbandryFood.capacity
503end

getFoodInfos

Description
Definition
getFoodInfos()
Code
395function PlaceableHusbandryFood:getFoodInfos(superFunc)
396 local foodInfos = superFunc(self)
397 local spec = self.spec_husbandryFood
398
399 local animalFood = g_currentMission.animalFoodSystem:getAnimalFood(spec.animalTypeIndex)
400
401 if animalFood ~= nil then
402 for _, foodGroup in pairs(animalFood.groups) do
403 local title = foodGroup.title
404 local fillLevel = 0
405 local capacity = spec.capacity
406
407 for _, fillTypeIndex in pairs(foodGroup.fillTypes) do
408 if spec.fillLevels[fillTypeIndex] ~= nil then
409 fillLevel = fillLevel + spec.fillLevels[fillTypeIndex]
410 end
411 end
412
413 local info = {}
414 info.title = string.format("%s (%d%%)", title, MathUtil.round(foodGroup.productionWeight*100))
415 info.value = fillLevel
416 info.capacity = capacity
417 info.ratio = 0
418 if capacity > 0 then
419 info.ratio = fillLevel / capacity
420 end
421
422 table.insert(foodInfos, info)
423 end
424 end
425
426 return foodInfos
427end

getFreeFoodCapacity

Description
Definition
getFreeFoodCapacity()
Code
507function PlaceableHusbandryFood:getFreeFoodCapacity(fillTypeIndex)
508 local spec = self.spec_husbandryFood
509 if spec.supportedFillTypes[fillTypeIndex] == nil then
510 return 0
511 end
512
513 return spec.capacity - self:getTotalFood()
514end

getSpecValueAnimalFoodFillTypes

Description
Definition
getSpecValueAnimalFoodFillTypes()
Code
693function PlaceableHusbandryFood.getSpecValueAnimalFoodFillTypes(storeItem, realItem)
694 local data = storeItem.specs.animalFoodFillTypes
695 if data == nil then
696 return nil
697 end
698
699 local fillTypes = {}
700 local animalType = g_currentMission.animalSystem:getTypeByName(data.animalTypeName)
701 if animalType == nil then
702 return nil
703 end
704
705 local animalFood = g_currentMission.animalFoodSystem:getAnimalFood(animalType.typeIndex)
706 local mixtures = g_currentMission.animalFoodSystem:getMixturesByAnimalTypeIndex(animalType.typeIndex)
707
708 if animalFood ~= nil then
709 for _, foodGroup in pairs(animalFood.groups) do
710 for _, fillTypeIndex in pairs(foodGroup.fillTypes) do
711 table.addElement(fillTypes, fillTypeIndex)
712 end
713 end
714 end
715
716 if mixtures ~= nil then
717 for _, foodMixtureFillType in ipairs(mixtures) do
718 table.addElement(fillTypes, foodMixtureFillType)
719 end
720 end
721
722 if data.needsWater then
723 table.addElement(fillTypes, FillType.WATER)
724 end
725
726 return fillTypes
727end

getTotalFood

Description
Definition
getTotalFood()
Code
489function PlaceableHusbandryFood:getTotalFood()
490 local spec = self.spec_husbandryFood
491 local fillLevel = 0
492 for _, level in pairs(spec.fillLevels) do
493 fillLevel = fillLevel + level
494 end
495
496 return fillLevel
497end

initSpecialization

Description
Definition
initSpecialization()
Code
88function PlaceableHusbandryFood.initSpecialization()
89 g_storeManager:addSpecType("animalFoodFillTypes", "shopListAttributeIconFillTypes", PlaceableHusbandryFood.loadSpecValueAnimalFoodFillTypes, PlaceableHusbandryFood.getSpecValueAnimalFoodFillTypes, "placeable")
90end

loadFromXMLFile

Description
Definition
loadFromXMLFile()
Code
332function PlaceableHusbandryFood:loadFromXMLFile(xmlFile, key)
333 local spec = self.spec_husbandryFood
334 xmlFile:iterate(key .. ".fillLevel", function(_, fillLevelKey)
335 local fillTypeName = xmlFile:getValue(fillLevelKey .. "#fillType")
336 local fillLevel = xmlFile:getValue(fillLevelKey .. "#fillLevel")
337 if fillTypeName ~= nil and fillLevel ~= nil then
338 local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(fillTypeName)
339 if fillTypeIndex ~= nil and spec.supportedFillTypes[fillTypeIndex] ~= nil then
340 self:addFood(self:getOwnerFarmId(), fillLevel, fillTypeIndex, nil, nil, nil)
341 end
342 end
343 end)
344end

loadSpecValueAnimalFoodFillTypes

Description
Definition
loadSpecValueAnimalFoodFillTypes()
Code
675function PlaceableHusbandryFood.loadSpecValueAnimalFoodFillTypes(xmlFile, customEnvironment, baseDir)
676 local data = nil
677
678 if xmlFile:hasProperty("placeable.husbandry.animals") then
679 data = data or {}
680 data.animalTypeName = xmlFile:getString("placeable.husbandry.animals#type")
681 end
682
683 if xmlFile:hasProperty("placeable.husbandry.water") then
684 data = data or {}
685 data.needsWater = not xmlFile:getValue("placeable.husbandry.water#automaticWaterSupply", false)
686 end
687
688 return data
689end

onDelete

Description
Definition
onDelete()
Code
201function PlaceableHusbandryFood:onDelete()
202 local spec = self.spec_husbandryFood
203
204 if spec.feedingTrough ~= nil then
205 spec.feedingTrough:delete()
206 spec.feedingTrough = nil
207 end
208
209 if spec.dynamicFoodPlane ~= nil then
210 delete(spec.dynamicFoodPlane)
211 spec.dynamicFoodPlane = nil
212 end
213
214 if spec.foodPlane ~= nil then
215 spec.foodPlane:delete()
216 spec.foodPlane = nil
217 end
218end

onFinalizePlacement

Description
Definition
onFinalizePlacement()
Code
222function PlaceableHusbandryFood:onFinalizePlacement()
223 local spec = self.spec_husbandryFood
224 if spec.feedingTrough ~= nil then
225 spec.feedingTrough:register(true)
226 end
227end

onHusbandryAnimalsCreated

Description
Definition
onHusbandryAnimalsCreated()
Code
463function PlaceableHusbandryFood:onHusbandryAnimalsCreated(husbandry)
464 if husbandry ~= nil then
465 local spec = self.spec_husbandryFood
466 spec.husbandry = husbandry
467 for _, foodPlace in ipairs(spec.foodPlaces) do
468 foodPlace.place = addFeedingPlace(husbandry, foodPlace.node, 0.0, AnimalHusbandryFeedingType.FOOD)
469 end
470 end
471end

onHusbandryAnimalsUpdate

Description
Definition
onHusbandryAnimalsUpdate()
Code
646function PlaceableHusbandryFood:onHusbandryAnimalsUpdate(clusters)
647 local spec = self.spec_husbandryFood
648
649 spec.litersPerHour = 0
650 for _, cluster in ipairs(clusters) do
651 local subType = g_currentMission.animalSystem:getSubTypeByIndex(cluster.subTypeIndex)
652 if subType ~= nil then
653 local food = subType.input.food
654 if food ~= nil then
655 local age = cluster:getAge()
656 local litersPerAnimal = food:get(age)
657 local litersPerDay = litersPerAnimal * cluster:getNumAnimals()
658
659 spec.litersPerHour = spec.litersPerHour + (litersPerDay / 24)
660 end
661 end
662 end
663end

onLoad

Description
Definition
onLoad()
Code
94function PlaceableHusbandryFood:onLoad(savegame)
95 local spec = self.spec_husbandryFood
96
97 spec.animalTypeIndex = nil
98 spec.litersPerHour = 0
99 spec.fillLevels = {}
100 spec.supportedFillTypes = {}
101 spec.fillTypes = {}
102 spec.lastPositionInfoSent = {0, 0}
103 spec.lastPositionInfo = {0, 0}
104 spec.foodPlaces = {}
105 spec.info = {title=g_i18n:getText("ui_animalFood"), text=""}
106
107 spec.dirtyFlagPosition = self:getNextDirtyFlag()
108 spec.dirtyFlagFillLevel = self:getNextDirtyFlag()
109
110 spec.capacity = self.xmlFile:getValue("placeable.husbandry.food#capacity", 5000)
111 spec.FILLLEVEL_NUM_BITS = MathUtil.getNumRequiredBits(spec.capacity)
112
113 local feedingTrough = UnloadTrigger.new(self.isServer, self.isClient)
114
115 local target = {
116 getIsFillTypeAllowed = function(_, fillTypeIndex)
117 return spec.supportedFillTypes[fillTypeIndex]
118 end,
119 getIsToolTypeAllowed = function(_, fillTypeIndex)
120 return true
121 end,
122 addFillLevelFromTool = function(_, ...)
123 return self:addFood(...)
124 end,
125 getFreeCapacity = function(_, fillTypeIndex)
126 return self:getFreeFoodCapacity(fillTypeIndex)
127 end
128 }
129 if not feedingTrough:load(self.components, self.xmlFile, "placeable.husbandry.food.feedingTrough", target, nil, self.i3dMappings) then
130 feedingTrough:delete()
131 self:setLoadingState(Placeable.LOADING_STATE_ERROR)
132 return
133 end
134
135 spec.feedingTrough = feedingTrough
136
137 spec.baseNode = self.xmlFile:getValue("placeable.husbandry.food.dynamicFoodPlane#node", nil, self.components, self.i3dMappings)
138 if spec.baseNode ~= nil then
139 local fillPlane = FillPlaneUtil.createFromXML(self.xmlFile, "placeable.husbandry.food.dynamicFoodPlane", spec.baseNode, spec.capacity)
140 local defaultFillTypeName = self.xmlFile:getValue("placeable.husbandry.food.dynamicFoodPlane#defaultFillType")
141 local defaultFillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(defaultFillTypeName) or FillType.FORAGE
142
143 if fillPlane ~= nil then
144 FillPlaneUtil.assignDefaultMaterials(fillPlane)
145 FillPlaneUtil.setFillType(fillPlane, defaultFillTypeIndex)
146
147 spec.dynamicFoodPlane = fillPlane
148 end
149 end
150
151 spec.foodPlane = FillPlane.new()
152 if spec.foodPlane:load(self.components, self.xmlFile, "placeable.husbandry.food.foodPlane", self.i3dMappings) then
153 local defaultFillTypeName = self.xmlFile:getValue("placeable.husbandry.food.foodPlane#defaultFillType")
154 local defaultFillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(defaultFillTypeName) or FillType.DRYGRASS_WINDROW
155
156 FillPlaneUtil.assignDefaultMaterials(spec.foodPlane.node)
157 FillPlaneUtil.setFillType(spec.foodPlane.node, defaultFillTypeIndex)
158 setShaderParameter(spec.foodPlane.node, "isCustomShape", 1, 0, 0, 0, false)
159 spec.foodPlane:setState(0)
160 else
161 spec.foodPlane:delete()
162 spec.foodPlane = nil
163 end
164
165 self.xmlFile:iterate("placeable.husbandry.food.foodPlaces.foodPlace", function(_, key)
166 local node = self.xmlFile:getValue(key .. "#node", nil, self.components, self.i3dMappings)
167 table.insert(spec.foodPlaces, {node=node, place=nil})
168 end)
169end

onPostFinalizePlacement

Description
Definition
onPostFinalizePlacement()
Code
231function PlaceableHusbandryFood:onPostFinalizePlacement()
232 self:updateFillPlanes()
233end

onPostLoad

Description
Definition
onPostLoad()
Code
173function PlaceableHusbandryFood:onPostLoad()
174 local spec = self.spec_husbandryFood
175 spec.animalTypeIndex = self:getAnimalTypeIndex()
176 local animalFood = g_currentMission.animalFoodSystem:getAnimalFood(spec.animalTypeIndex)
177 local mixtures = g_currentMission.animalFoodSystem:getMixturesByAnimalTypeIndex(spec.animalTypeIndex)
178
179 if animalFood ~= nil then
180 for _, foodGroup in pairs(animalFood.groups) do
181 for _, fillTypeIndex in pairs(foodGroup.fillTypes) do
182 if spec.fillLevels[fillTypeIndex] == nil then
183 spec.fillLevels[fillTypeIndex] = 0.0
184 spec.supportedFillTypes[fillTypeIndex] = true
185 table.insert(spec.fillTypes, fillTypeIndex)
186 end
187 end
188 end
189 end
190
191 if mixtures ~= nil then
192 for _, foodMixtureFillType in ipairs(mixtures) do
193 spec.supportedFillTypes[foodMixtureFillType] = true
194 table.insert(spec.fillTypes, foodMixtureFillType)
195 end
196 end
197end

onReadStream

Description
Definition
onReadStream()
Code
237function PlaceableHusbandryFood:onReadStream(streamId, connection)
238 local spec = self.spec_husbandryFood
239 for _, fillTypeIndex in ipairs(spec.fillTypes) do
240 if spec.fillLevels[fillTypeIndex] ~= nil then
241 spec.fillLevels[fillTypeIndex] = streamReadUIntN(streamId, spec.FILLLEVEL_NUM_BITS)
242 end
243 end
244
245-- local totalFillLevel = self:getTotalFood()
246-- if spec.dynamicFoodPlane ~= nil then
247-- readFillPlaneFromStream(spec.dynamicFoodPlane, streamId, totalFillLevel)
248-- end
249
250 if spec.feedingTrough ~= nil then
251 local feedingTroughId = NetworkUtil.readNodeObjectId(streamId)
252 spec.feedingTrough:readStream(streamId, connection)
253 g_client:finishRegisterObject(spec.feedingTrough, feedingTroughId)
254 end
255end

onReadUpdateStream

Description
Definition
onReadUpdateStream()
Code
280function PlaceableHusbandryFood:onReadUpdateStream(streamId, timestamp, connection)
281 if connection:getIsServer() then
282 local spec = self.spec_husbandryFood
283 if streamReadBool(streamId) then
284 local x = (streamReadUIntN(streamId, FillVolume.SEND_NUM_BITS) / (math.pow(2, FillVolume.SEND_NUM_BITS) - 1) * FillVolume.SEND_MAX_SIZE) - FillVolume.SEND_MAX_SIZE * 0.5
285 local z = (streamReadUIntN(streamId, FillVolume.SEND_NUM_BITS) / (math.pow(2, FillVolume.SEND_NUM_BITS) - 1) * FillVolume.SEND_MAX_SIZE) - FillVolume.SEND_MAX_SIZE * 0.5
286
287 spec.lastPositionInfo[1] = x
288 spec.lastPositionInfo[2] = z
289 end
290
291 if streamReadBool(streamId) then
292 for _, fillTypeIndex in ipairs(spec.fillTypes) do
293 if spec.fillLevels[fillTypeIndex] ~= nil then
294 local newFillLevel = streamReadUIntN(streamId, spec.FILLLEVEL_NUM_BITS)
295 local delta = newFillLevel - spec.fillLevels[fillTypeIndex]
296 if delta > 0 then
297 self:addFood(self:getOwnerFarmId(), delta, fillTypeIndex, nil, nil, nil)
298 else
299 self:removeFood(math.abs(delta), fillTypeIndex)
300 end
301 end
302 end
303 end
304 end
305end

onWriteStream

Description
Definition
onWriteStream()
Code
259function PlaceableHusbandryFood:onWriteStream(streamId, connection)
260 local spec = self.spec_husbandryFood
261 for _, fillTypeIndex in ipairs(spec.fillTypes) do
262 if spec.fillLevels[fillTypeIndex] ~= nil then
263 streamWriteUIntN(streamId, spec.fillLevels[fillTypeIndex], spec.FILLLEVEL_NUM_BITS)
264 end
265 end
266
267-- if spec.dynamicFoodPlane ~= nil then
268-- writeFillPlaneToStream(spec.dynamicFoodPlane, streamId)
269-- end
270
271 if spec.feedingTrough ~= nil then
272 NetworkUtil.writeNodeObjectId(streamId, NetworkUtil.getObjectId(spec.feedingTrough))
273 spec.feedingTrough:writeStream(streamId, connection)
274 g_server:registerObjectInStream(connection, spec.feedingTrough)
275 end
276end

onWriteUpdateStream

Description
Definition
onWriteUpdateStream()
Code
309function PlaceableHusbandryFood:onWriteUpdateStream(streamId, connection, dirtyMask)
310 if not connection:getIsServer() then
311 local spec = self.spec_husbandryFood
312 if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlagPosition) ~= 0) then
313 local x = (spec.lastPositionInfoSent[1] + FillVolume.SEND_MAX_SIZE * 0.5) / FillVolume.SEND_MAX_SIZE * (math.pow(2, FillVolume.SEND_NUM_BITS) - 1)
314 streamWriteUIntN(streamId, x, FillVolume.SEND_NUM_BITS)
315
316 local z = (spec.lastPositionInfoSent[2] + FillVolume.SEND_MAX_SIZE * 0.5) / FillVolume.SEND_MAX_SIZE * (math.pow(2, FillVolume.SEND_NUM_BITS) - 1)
317 streamWriteUIntN(streamId, z, FillVolume.SEND_NUM_BITS)
318 end
319
320 if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlagFillLevel) ~= 0) then
321 for _, fillTypeIndex in ipairs(spec.fillTypes) do
322 if spec.fillLevels[fillTypeIndex] ~= nil then
323 streamWriteUIntN(streamId, spec.fillLevels[fillTypeIndex], spec.FILLLEVEL_NUM_BITS)
324 end
325 end
326 end
327 end
328end

prerequisitesPresent

Description
Checks if all prerequisite specializations are loaded
Definition
prerequisitesPresent(table specializations)
Arguments
tablespecializationsspecializations
Return Values
booleanhasPrerequisitetrue if all prerequisite specializations are loaded
Code
18function PlaceableHusbandryFood.prerequisitesPresent(specializations)
19 return true
20end

registerEventListeners

Description
Definition
registerEventListeners()
Code
46function PlaceableHusbandryFood.registerEventListeners(placeableType)
47 SpecializationUtil.registerEventListener(placeableType, "onLoad", PlaceableHusbandryFood)
48 SpecializationUtil.registerEventListener(placeableType, "onPostLoad", PlaceableHusbandryFood)
49 SpecializationUtil.registerEventListener(placeableType, "onDelete", PlaceableHusbandryFood)
50 SpecializationUtil.registerEventListener(placeableType, "onFinalizePlacement", PlaceableHusbandryFood)
51 SpecializationUtil.registerEventListener(placeableType, "onPostFinalizePlacement", PlaceableHusbandryFood)
52 SpecializationUtil.registerEventListener(placeableType, "onReadStream", PlaceableHusbandryFood)
53 SpecializationUtil.registerEventListener(placeableType, "onWriteStream", PlaceableHusbandryFood)
54 SpecializationUtil.registerEventListener(placeableType, "onReadUpdateStream", PlaceableHusbandryFood)
55 SpecializationUtil.registerEventListener(placeableType, "onWriteUpdateStream", PlaceableHusbandryFood)
56 SpecializationUtil.registerEventListener(placeableType, "onHusbandryAnimalsUpdate", PlaceableHusbandryFood)
57 SpecializationUtil.registerEventListener(placeableType, "onHusbandryAnimalsCreated", PlaceableHusbandryFood)
58end

registerFunctions

Description
Definition
registerFunctions()
Code
24function PlaceableHusbandryFood.registerFunctions(placeableType)
25 SpecializationUtil.registerFunction(placeableType, "updateFillPlanes", PlaceableHusbandryFood.updateFillPlanes)
26 SpecializationUtil.registerFunction(placeableType, "updateFoodPlaces", PlaceableHusbandryFood.updateFoodPlaces)
27 SpecializationUtil.registerFunction(placeableType, "addFood", PlaceableHusbandryFood.addFood)
28 SpecializationUtil.registerFunction(placeableType, "removeFood", PlaceableHusbandryFood.removeFood)
29 SpecializationUtil.registerFunction(placeableType, "getTotalFood", PlaceableHusbandryFood.getTotalFood)
30 SpecializationUtil.registerFunction(placeableType, "getFoodCapacity", PlaceableHusbandryFood.getFoodCapacity)
31 SpecializationUtil.registerFunction(placeableType, "getFreeFoodCapacity", PlaceableHusbandryFood.getFreeFoodCapacity)
32end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
36function PlaceableHusbandryFood.registerOverwrittenFunctions(placeableType)
37 SpecializationUtil.registerOverwrittenFunction(placeableType, "updateInfo", PlaceableHusbandryFood.updateInfo)
38 SpecializationUtil.registerOverwrittenFunction(placeableType, "updateFeeding", PlaceableHusbandryFood.updateFeeding)
39 SpecializationUtil.registerOverwrittenFunction(placeableType, "getFoodInfos", PlaceableHusbandryFood.getFoodInfos)
40 SpecializationUtil.registerOverwrittenFunction(placeableType, "collectPickObjects", PlaceableHusbandryFood.collectPickObjects)
41 SpecializationUtil.registerOverwrittenFunction(placeableType, "getAnimalDescription", PlaceableHusbandryFood.getAnimalDescription)
42end

registerSavegameXMLPaths

Description
Definition
registerSavegameXMLPaths()
Code
79function PlaceableHusbandryFood.registerSavegameXMLPaths(schema, basePath)
80 schema:setXMLSpecializationType("Husbandry")
81 schema:register(XMLValueType.STRING, basePath .. ".fillLevel(?)#fillType", "Fill type")
82 schema:register(XMLValueType.FLOAT, basePath .. ".fillLevel(?)#fillLevel", "Fill level")
83 schema:setXMLSpecializationType()
84end

registerXMLPaths

Description
Definition
registerXMLPaths()
Code
62function PlaceableHusbandryFood.registerXMLPaths(schema, basePath)
63 schema:setXMLSpecializationType("Husbandry")
64 basePath = basePath .. ".husbandry.food"
65 schema:register(XMLValueType.INT, basePath .. "#capacity", "Trough capacity", 5000)
66 schema:register(XMLValueType.NODE_INDEX, basePath .. ".foodPlaces.foodPlace(?)#node", "Foodplace")
67
68 schema:register(XMLValueType.NODE_INDEX, basePath .. ".dynamicFoodPlane#node", "Node")
69 schema:register(XMLValueType.STRING, basePath .. ".dynamicFoodPlane#defaultFillType", "Fillplane default filltype")
70 FillPlaneUtil.registerFillPlaneXMLPaths(schema, basePath .. ".dynamicFoodPlane")
71 FillPlane.registerXMLPaths(schema, basePath .. ".foodPlane", "Fillplane")
72 schema:register(XMLValueType.STRING, basePath .. ".foodPlane#defaultFillType", "Fillplane default filltype")
73 UnloadTrigger.registerXMLPaths(schema, basePath .. ".feedingTrough")
74 schema:setXMLSpecializationType()
75end

removeFood

Description
Definition
removeFood()
Code
608function PlaceableHusbandryFood:removeFood(absDeltaFillLevel, fillTypeIndex)
609 local spec = self.spec_husbandryFood
610 if spec.supportedFillTypes[fillTypeIndex] == nil then
611 return 0
612 end
613
614 if absDeltaFillLevel <= 0 then
615 return 0
616 end
617
618 absDeltaFillLevel = math.min(math.abs(absDeltaFillLevel), spec.fillLevels[fillTypeIndex])
619
620 if spec.dynamicFoodPlane ~= nil then
621 local x,y,z = localToWorld(spec.dynamicFoodPlane, 0,0,0)
622 local d1x,d1y,d1z = localDirectionToWorld(spec.dynamicFoodPlane, 0.1, 0, 0)
623 local d2x,d2y,d2z = localDirectionToWorld(spec.dynamicFoodPlane, 0, 0, 0.1)
624
625 local steps = MathUtil.clamp(math.floor(absDeltaFillLevel/400), 1, 25)
626 local delta = absDeltaFillLevel/steps
627 for _=1, steps do
628 fillPlaneAdd(spec.dynamicFoodPlane, -delta, x,y,z, d1x,d1y,d1z, d2x,d2y,d2z)
629 end
630 end
631
632 spec.fillLevels[fillTypeIndex] = spec.fillLevels[fillTypeIndex] - absDeltaFillLevel
633
634 if self.isServer then
635 self:raiseDirtyFlags(spec.dirtyFlagFillLevel)
636 end
637
638 self:updateFillPlanes()
639 self:updateFoodPlaces()
640
641 return absDeltaFillLevel
642end

saveToXMLFile

Description
Definition
saveToXMLFile()
Code
348function PlaceableHusbandryFood:saveToXMLFile(xmlFile, key, usedModNames)
349 local spec = self.spec_husbandryFood
350 local index = 0
351 for fillTypeIndex, fillLevel in pairs(spec.fillLevels) do
352 if fillLevel > 0 then
353 local fillTypeName = g_fillTypeManager:getFillTypeNameByIndex(fillTypeIndex)
354 if fillTypeName ~= nil then
355 local fillLevelKey = string.format("%s.fillLevel(%d)", key, index)
356 xmlFile:setValue(fillLevelKey.."#fillType", fillTypeName)
357 xmlFile:setValue(fillLevelKey.."#fillLevel", fillLevel)
358 index = index + 1
359 end
360 end
361 end
362end

updateFeeding

Description
Definition
updateFeeding()
Code
366function PlaceableHusbandryFood:updateFeeding(superFunc)
367 local factor = superFunc(self)
368 local spec = self.spec_husbandryFood
369
370 if self.isServer and spec.animalTypeIndex ~= nil then
371 local consumedFood = {}
372 factor = factor * g_currentMission.animalFoodSystem:consumeFood(spec.animalTypeIndex, spec.litersPerHour * g_currentMission.environment.timeAdjustment, spec.fillLevels, consumedFood)
373
374 for fillTypeIndex, delta in pairs(consumedFood) do
375 self:removeFood(delta, fillTypeIndex)
376 end
377 end
378
379 return factor
380end

updateFillPlanes

Description
Definition
updateFillPlanes()
Code
431function PlaceableHusbandryFood:updateFillPlanes(fillTypeIndex)
432 local spec = self.spec_husbandryFood
433 if spec.foodPlane ~= nil then
434 local fillLevel = self:getTotalFood()
435 local capacity = self:getFoodCapacity()
436 local state = 0
437 if capacity > 0 then
438 state = fillLevel / capacity
439 end
440 spec.foodPlane:setState(state)
441
442 if state > 0 and fillTypeIndex ~= nil then
443 FillPlaneUtil.assignDefaultMaterials(spec.foodPlane.node)
444 FillPlaneUtil.setFillType(spec.foodPlane.node, fillTypeIndex)
445 setShaderParameter(spec.foodPlane.node, "isCustomShape", 1, 0, 0, 0, false)
446 end
447 end
448end

updateFoodPlaces

Description
Definition
updateFoodPlaces()
Code
475function PlaceableHusbandryFood:updateFoodPlaces()
476 local spec = self.spec_husbandryFood
477 if spec.husbandry ~= nil then
478 local fillLevel = self:getTotalFood()
479 for _, foodPlace in pairs(spec.foodPlaces) do
480 if foodPlace.place ~= nil then
481 updateFeedingPlace(spec.husbandry, foodPlace.place, fillLevel)
482 end
483 end
484 end
485end

updateInfo

Description
Definition
updateInfo()
Code
384function PlaceableHusbandryFood:updateInfo(superFunc, infoTable)
385 superFunc(self, infoTable)
386 local spec = self.spec_husbandryFood
387
388 local fillLevel = self:getTotalFood()
389 spec.info.text = string.format("%d l", fillLevel)
390 table.insert(infoTable, spec.info)
391end