LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

PlaceableHusbandryAnimals

Description
Specialization for placeables
Functions

addAnimals

Description
Definition
addAnimals()
Code
568function PlaceableHusbandryAnimals:addAnimals(subTypeIndex, numAnimals, age)
569 local cluster = g_currentMission.animalSystem:createClusterFromSubTypeIndex(subTypeIndex)
570 if cluster:getSupportsMerging() then
571 cluster.numAnimals = numAnimals
572 cluster.age = age
573 cluster.subTypeIndex = subTypeIndex
574 self:addCluster(cluster)
575 else
576 for i=1, numAnimals do
577 cluster = g_currentMission.animalSystem:createClusterFromSubTypeIndex(subTypeIndex)
578 cluster.numAnimals = 1
579 cluster.age = age
580 self:addCluster(cluster)
581 end
582 end
583end

addCluster

Description
Definition
addCluster()
Code
558function PlaceableHusbandryAnimals:addCluster(cluster)
559 if cluster ~= nil then
560 local spec = self.spec_husbandryAnimals
561 spec.clusterSystem:addPendingAddCluster(cluster)
562 self:raiseActive()
563 end
564end

canBeSold

Description
Definition
canBeSold()
Code
789function PlaceableHusbandryAnimals:canBeSold(superFunc)
790 if self:getNumOfAnimals() > 0 then
791 return false, g_i18n:getText("info_husbandryNotEmpty")
792 end
793
794 return superFunc(self)
795end

consoleCommandAddAnimals

Description
Definition
consoleCommandAddAnimals()
Code
837function PlaceableHusbandryAnimals.consoleCommandAddAnimals(_, numAnimals, subTypeIndex)
838 local usage = 'Usage: gsHusbandryAddAnimals numAnimals [subTypeIndex]\nUse negative number to remove animals'
839
840 local x,y,z = getWorldTranslation(getCamera(0))
841 raycastAll(x,y+100,z, 0, -1, 0, "consoleCommandAddAnimalsRaycastCallback", 110, PlaceableHusbandryAnimals)
842
843 local husbandryInstance = PlaceableHusbandryAnimals.consoleCommandCurrentHusbandry
844 PlaceableHusbandryAnimals.consoleCommandCurrentHusbandry = nil
845 if husbandryInstance == nil then
846 return "Error: No husbandry found. Enter a husbandry with the player first"
847 end
848 local spec = husbandryInstance.spec_husbandryAnimals
849
850 numAnimals = tonumber(numAnimals) or 0
851 subTypeIndex = tonumber(subTypeIndex)
852
853 if numAnimals > 0 then
854 if husbandryInstance:getNumOfFreeAnimalSlots() == 0 then
855 return "Error: Husbandry is full"
856 end
857
858 numAnimals = math.min(numAnimals, husbandryInstance:getNumOfFreeAnimalSlots())
859 subTypeIndex = tonumber(subTypeIndex) or 1
860
861 local globalSubTypeIndex = spec.animalType.subTypes[subTypeIndex]
862 if globalSubTypeIndex ~= nil then
863 local newCluster = g_currentMission.animalSystem:createClusterFromSubTypeIndex(globalSubTypeIndex)
864 newCluster.numAnimals = numAnimals
865 spec.clusterSystem:addPendingAddCluster(newCluster)
866 husbandryInstance:raiseActive()
867
868 return "Added "..numAnimals.." animal(s)"
869 else
870 return "Error: Invalid subtype index\n" .. usage
871 end
872 elseif numAnimals < 0 then
873 local remainingAnimals = numAnimals
874 for _, cluster in pairs(husbandryInstance:getClusters()) do
875 if subTypeIndex == nil or cluster:getSubTypeIndex() == subTypeIndex then
876 remainingAnimals = cluster:changeNumAnimals(remainingAnimals)
877 end
878 if remainingAnimals >= 0 then
879 break
880 end
881 end
882 if numAnimals ~= remainingAnimals then
883 return string.format("Removed %d animal(s)", math.abs(numAnimals - remainingAnimals))
884 end
885 if subTypeIndex ~= nil then
886 return "Error: Husbandry has no animals of subtype " .. subTypeIndex
887 end
888 return "Error: Husbandry has no animals"
889 end
890
891 return "Error: Invalid number of animals\n" .. usage
892end

createHusbandry

Description
Definition
createHusbandry()
Code
337function PlaceableHusbandryAnimals:createHusbandry()
338 local spec = self.spec_husbandryAnimals
339 if spec.navigationMesh == nil then
340 Logging.error("Navigation mesh node not defined for animal husbandry!")
341 return
342 end
343
344 if not getHasClassId(spec.navigationMesh, ClassIds.NAVIGATION_MESH) then
345 Logging.error("Given mesh node '%s' is not a navigation mesh!", getName(spec.navigationMesh))
346 return
347 end
348
349 local collisionMaskFilter = CollisionMask.ANIMAL_SINGLEPLAYER
350 if g_currentMission.missionDynamicInfo.isMultiplayer then
351 collisionMaskFilter = CollisionMask.ANIMAL_MULTIPLAYER
352 end
353
354 local xmlFilename = Utils.getFilename(spec.animalType.configFilename, spec.baseDirectory)
355 local husbandry = spec.clusterHusbandry:create(xmlFilename, spec.navigationMesh, spec.placementRaycastDistance, collisionMaskFilter)
356
357 if husbandry == nil or husbandry == 0 then
358 Logging.error("Could not create animal husbandry!")
359 return
360 end
361
362 if husbandry ~= nil then
363 g_currentMission.husbandrySystem:addClusterHusbandry(spec.clusterHusbandry)
364 end
365
366 SpecializationUtil.raiseEvent(self, "onHusbandryAnimalsCreated", husbandry)
367end

getAnimalCanBeRidden

Description
Definition
getAnimalCanBeRidden()
Code
637function PlaceableHusbandryAnimals:getAnimalCanBeRidden(clusterId)
638 return g_currentMission.husbandrySystem:getCanAddRideable(self:getOwnerFarmId())
639end

getAnimalDescription

Description
Definition
getAnimalDescription()
Code
827function PlaceableHusbandryAnimals:getAnimalDescription(superFunc, cluster)
828 local text = superFunc(self, cluster)
829
830 local visual = g_currentMission.animalSystem:getVisualByAge(cluster.subTypeIndex, cluster:getAge())
831
832 return text .. visual.store.description
833end

getAnimalInfos

Description
Definition
getAnimalInfos()
Code
817function PlaceableHusbandryAnimals:getAnimalInfos(superFunc, cluster)
818 local infos = superFunc(self)
819
820 cluster:addInfos(infos)
821
822 return infos
823end

getAnimalSupportsRiding

Description
Definition
getAnimalSupportsRiding()
Code
622function PlaceableHusbandryAnimals:getAnimalSupportsRiding(clusterId)
623 local spec = self.spec_husbandryAnimals
624 local cluster = spec.clusterSystem:getClusterById(clusterId)
625 if cluster ~= nil then
626 local filename = cluster:getRidableFilename()
627 if filename ~= nil then
628 return true
629 end
630 end
631
632 return false
633end

getAnimalTypeIndex

Description
Definition
getAnimalTypeIndex()
Code
420function PlaceableHusbandryAnimals:getAnimalTypeIndex()
421 local spec = self.spec_husbandryAnimals
422 return spec.animalTypeIndex
423end

getCluster

Description
Definition
getCluster()
Code
544function PlaceableHusbandryAnimals:getCluster(index)
545 local spec = self.spec_husbandryAnimals
546 return spec.clusterSystem:getCluster(index)
547end

getClusterById

Description
Definition
getClusterById()
Code
551function PlaceableHusbandryAnimals:getClusterById(id)
552 local spec = self.spec_husbandryAnimals
553 return spec.clusterSystem:getClusterById(id)
554end

getClusters

Description
Definition
getClusters()
Code
537function PlaceableHusbandryAnimals:getClusters()
538 local spec = self.spec_husbandryAnimals
539 return spec.clusterSystem:getClusters()
540end

getClusterSystem

Description
Definition
getClusterSystem()
Code
587function PlaceableHusbandryAnimals:getClusterSystem()
588 local spec = self.spec_husbandryAnimals
589 return spec.clusterSystem
590end

getConditionInfos

Description
Definition
getConditionInfos()
Code
799function PlaceableHusbandryAnimals:getConditionInfos(superFunc)
800 local infos = superFunc(self)
801 local spec = self.spec_husbandryAnimals
802
803 local animalTypeIndex = self:getAnimalTypeIndex()
804 if animalTypeIndex ~= AnimalType.HORSE and animalTypeIndex ~= AnimalType.PIG then
805 local productivity = self:getGlobalProductionFactor()
806 spec.info.value = productivity
807 spec.info.ratio = productivity
808 spec.info.valueText = string.format("%d %%", g_i18n:formatNumber(productivity*100, 0))
809 table.insert(infos, spec.info)
810 end
811
812 return infos
813end

getIsInAnimalDeliveryArea

Description
Definition
getIsInAnimalDeliveryArea()
Code
718function PlaceableHusbandryAnimals:getIsInAnimalDeliveryArea(x, z)
719 local spec = self.spec_husbandryAnimals
720 for _, deliveryArea in ipairs(spec.deliveryAreas) do
721
722 local startX, _, startZ = getWorldTranslation(deliveryArea.start)
723 local widthX, _, widthZ = getWorldTranslation(deliveryArea.width)
724 local heightX, _, heightZ = getWorldTranslation(deliveryArea.height)
725
726 widthX, widthZ = widthX-startX, widthZ-startZ
727 heightX, heightZ = heightX-startX, heightZ-startZ
728
729 local inArea = MathUtil.isPointInParallelogram(x, z, startX, startZ, widthX, widthZ, heightX, heightZ)
730
731 if inArea then
732 return true
733 end
734 end
735
736 if #spec.deliveryAreas == 0 then
737 local px, _, pz = getWorldTranslation(self.rootNode)
738 if MathUtil.vector2Length(px-x, pz-z) < 30 then
739 return true
740 end
741 end
742
743 return false
744
745end

getMaxNumOfAnimals

Description
Definition
getMaxNumOfAnimals()
Code
505function PlaceableHusbandryAnimals:getMaxNumOfAnimals()
506 local spec = self.spec_husbandryAnimals
507 return spec.maxNumAnimals
508end

getNeedDayChanged

Description
Definition
getNeedDayChanged()
Code
396function PlaceableHusbandryAnimals:getNeedDayChanged(superFunc)
397 return true
398end

getNumOfAnimals

Description
Definition
getNumOfAnimals()
Code
492function PlaceableHusbandryAnimals:getNumOfAnimals()
493 local spec = self.spec_husbandryAnimals
494 local numAnimals = 0
495 local clusters = spec.clusterSystem:getClusters()
496 for _, cluster in ipairs(clusters) do
497 numAnimals = numAnimals + cluster.numAnimals
498 end
499
500 return numAnimals
501end

getNumOfClusters

Description
Definition
getNumOfClusters()
Code
529function PlaceableHusbandryAnimals:getNumOfClusters()
530 local spec = self.spec_husbandryAnimals
531 local clusters = spec.clusterSystem:getClusters()
532 return #clusters
533end

getNumOfFreeAnimalSlots

Description
Definition
getNumOfFreeAnimalSlots()
Code
512function PlaceableHusbandryAnimals:getNumOfFreeAnimalSlots()
513 local spec = self.spec_husbandryAnimals
514 local totalNumAnimals = self:getNumOfAnimals()
515 return math.max(spec.maxNumAnimals - totalNumAnimals, 0)
516end

getSpecValueNumberAnimals

Description
Definition
getSpecValueNumberAnimals()
Code
763function PlaceableHusbandryAnimals.getSpecValueNumberAnimals(storeItem, realItem)
764 local data = storeItem.specs.numberAnimals
765 if data == nil then
766 return nil
767 end
768
769 local profile = nil
770
771 local animalTypeIndex = g_currentMission.animalSystem:getTypeIndexByName(data.animalTypeName)
772 if animalTypeIndex == AnimalType.COW then
773 profile = "shopListAttributeIconCow"
774 elseif animalTypeIndex == AnimalType.SHEEP then
775 profile = "shopListAttributeIconSheep"
776 elseif animalTypeIndex == AnimalType.HORSE then
777 profile = "shopListAttributeIconHorse"
778 elseif animalTypeIndex == AnimalType.PIG then
779 profile = "shopListAttributeIconPig"
780 elseif animalTypeIndex == AnimalType.CHICKEN then
781 profile = "shopListAttributeIconChicken"
782 end
783
784 return data.maxNumAnimals, profile
785end

getSupportsAnimalSubType

Description
Definition
getSupportsAnimalSubType()
Code
520function PlaceableHusbandryAnimals:getSupportsAnimalSubType(subTypeIndex)
521 local spec = self.spec_husbandryAnimals
522 local animalSystem = g_currentMission.animalSystem
523 local subType = animalSystem:getSubTypeByIndex(subTypeIndex)
524 return spec.animalTypeIndex == subType.typeIndex
525end

initSpecialization

Description
Definition
initSpecialization()
Code
113function PlaceableHusbandryAnimals.initSpecialization()
114 g_storeManager:addSpecType("numberAnimals", "shopListAttributeIconCapacity", PlaceableHusbandryAnimals.loadSpecValueNumberAnimals, PlaceableHusbandryAnimals.getSpecValueNumberAnimals, "placeable")
115
116 if g_isDevelopmentVersion then
117 addConsoleCommand("gsHusbandryAddAnimals", "Add or remove animals from husbandry where player is currently located", "consoleCommandAddAnimals", PlaceableHusbandryAnimals)
118 end
119end

loadDeliveryArea

Description
Definition
loadDeliveryArea()
Code
690function PlaceableHusbandryAnimals:loadDeliveryArea(xmlFile, key, area)
691 local start = xmlFile:getValue(key .. "#startNode", nil, self.components, self.i3dMappings)
692 if start == nil then
693 Logging.xmlWarning(xmlFile, "Delivery area start node not defined for '%s'", key)
694 return false
695 end
696
697 local width = xmlFile:getValue(key .. "#widthNode", nil, self.components, self.i3dMappings)
698 if width == nil then
699 Logging.xmlWarning(xmlFile, "Delivery area width node not defined for '%s'", key)
700 return false
701 end
702
703 local height = xmlFile:getValue(key .. "#heightNode", nil, self.components, self.i3dMappings)
704 if height == nil then
705 Logging.xmlWarning(xmlFile, "Delivery area height node not defined for '%s'", key)
706 return false
707 end
708
709 area.start = start
710 area.width = width
711 area.height = height
712
713 return true
714end

loadFromXMLFile

Description
Definition
loadFromXMLFile()
Code
288function PlaceableHusbandryAnimals:loadFromXMLFile(xmlFile, key)
289 local spec = self.spec_husbandryAnimals
290 spec.clusterSystem:loadFromXMLFile(xmlFile, key .. ".clusters")
291end

loadSpecValueNumberAnimals

Description
Definition
loadSpecValueNumberAnimals()
Code
749function PlaceableHusbandryAnimals.loadSpecValueNumberAnimals(xmlFile, customEnvironment, baseDir)
750 local data = nil
751
752 if xmlFile:hasProperty("placeable.husbandry.animals") then
753 local maxNumAnimals = xmlFile:getInt("placeable.husbandry.animals#maxNumAnimals", 16)
754 local animalTypeName = xmlFile:getString("placeable.husbandry.animals#type")
755 data = {maxNumAnimals=maxNumAnimals, animalTypeName=animalTypeName}
756 end
757
758 return data
759end

onDayChanged

Description
Definition
onDayChanged()
Code
480function PlaceableHusbandryAnimals:onDayChanged()
481 if self.isServer then
482 local spec = self.spec_husbandryAnimals
483 local clusters = spec.clusterSystem:getClusters()
484 for _, cluster in ipairs(clusters) do
485 cluster:onDayChanged()
486 end
487 end
488end

onDelete

Description
Definition
onDelete()
Code
234function PlaceableHusbandryAnimals:onDelete()
235 local spec = self.spec_husbandryAnimals
236
237 g_messageCenter:unsubscribe(AnimalClusterUpdateEvent, self)
238
239 if spec.clusterHusbandry ~= nil then
240 g_currentMission.husbandrySystem:removeClusterHusbandry(spec.clusterHusbandry)
241 spec.clusterHusbandry:delete()
242 spec.clusterHusbandry = nil
243 end
244 if spec.animalLoadingTrigger ~= nil then
245 spec.animalLoadingTrigger:delete()
246 spec.animalLoadingTrigger = nil
247 end
248
249 if spec.sharedLoadRequestId ~= nil then
250 g_i3DManager:releaseSharedI3DFile(spec.sharedLoadRequestId)
251 end
252
253 g_currentMission:unregisterObjectToCallOnMissionStart(self)
254end

onExternalNavigationMeshLoaded

Description
Definition
onExternalNavigationMeshLoaded()
Code
317function PlaceableHusbandryAnimals:onExternalNavigationMeshLoaded(node, failedReason, args)
318 local spec = self.spec_husbandryAnimals
319
320 local loadingTask = args.loadingTask
321
322 if node == 0 or node == nil then
323 self:finishLoadingTask(loadingTask)
324 Logging.error("Missing navigation mesh in external navigation mesh file!")
325 return
326 end
327
328 spec.navigationMesh = I3DUtil.indexToObject(node, spec.navigationMeshNodePath)
329 link(spec.navigationMeshRootNode, spec.navigationMesh)
330 delete(node)
331
332 self:finishLoadingTask(loadingTask)
333end

onFinalizePlacement

Description
Definition
onFinalizePlacement()
Code
258function PlaceableHusbandryAnimals:onFinalizePlacement()
259 -- load navigation mesh
260 self:createHusbandry()
261
262 g_currentMission:registerObjectToCallOnMissionStart(self)
263end

onLoad

Description
Definition
onLoad()
Code
123function PlaceableHusbandryAnimals:onLoad(savegame)
124 local spec = self.spec_husbandryAnimals
125 local xmlFile = self.xmlFile
126
127 spec.infoHealth = {title=g_i18n:getText("ui_horseHealth"), text=""}
128 spec.infoNumAnimals = {title=g_i18n:getText("ui_numAnimals"), text=""}
129 spec.updateVisuals = false
130
131 local animalTypeName = xmlFile:getValue("placeable.husbandry.animals#type")
132 if animalTypeName == nil then
133 Logging.xmlError(xmlFile, "Missing animal type!")
134 self:setLoadingState(Placeable.LOADING_STATE_ERROR)
135 return
136 end
137
138 spec.animalType = g_currentMission.animalSystem:getTypeByName(animalTypeName)
139 if spec.animalType == nil then
140 Logging.xmlError(xmlFile, "Animal type '%s' not found!", animalTypeName)
141 self:setLoadingState(Placeable.LOADING_STATE_ERROR)
142 return
143 end
144
145 spec.animalTypeIndex = spec.animalType.typeIndex
146
147 spec.navigationMeshRootNode = xmlFile:getValue("placeable.husbandry.animals.navigation#rootNode", nil, self.components, self.i3dMappings)
148 spec.navigationMesh = xmlFile:getValue("placeable.husbandry.animals.navigation#node", nil, self.components, self.i3dMappings)
149 local navigationMeshFilename = xmlFile:getValue("placeable.husbandry.animals.navigation#filename", nil)
150 if navigationMeshFilename ~= nil then
151 navigationMeshFilename = Utils.getFilename(navigationMeshFilename, self.baseDirectory)
152 local loadingTask = self:createLoadingTask(spec)
153 spec.navigationMeshNodePath = xmlFile:getValue("placeable.husbandry.animals.navigation#nodePath", "0")
154
155 local arguments = {
156 loadingTask = loadingTask
157 }
158 spec.sharedLoadRequestId = g_i3DManager:loadSharedI3DFileAsync(navigationMeshFilename, true, false, self.onExternalNavigationMeshLoaded, self, arguments)
159 end
160
161 spec.placementRaycastDistance = xmlFile:getValue("placeable.husbandry.animals#placementRaycastDistance", 10.0)
162 spec.maxNumAnimals = xmlFile:getValue("placeable.husbandry.animals#maxNumAnimals", 16)
163
164 if spec.animalTypeIndex == AnimalType.HORSE then
165 spec.maxNumVisualAnimals = math.min(spec.maxNumAnimals, 16)
166 spec.maxNumAnimals = math.min(spec.maxNumAnimals, 16)
167 else
168 local profileClass = Utils.getPerformanceClassId()
169 if GS_PLATFORM_XBOX or profileClass == GS_PROFILE_LOW then
170 spec.maxNumVisualAnimals = 10
171 elseif profileClass >= GS_PROFILE_VERY_HIGH then
172 spec.maxNumVisualAnimals = 25
173 elseif profileClass >= GS_PROFILE_HIGH then
174 spec.maxNumVisualAnimals = 20
175 else
176 spec.maxNumVisualAnimals = 16
177 end
178 end
179
180 local maxAnimals = (2^AnimalCluster.NUM_BITS_NUM_ANIMALS) - 1
181 if spec.maxNumAnimals > maxAnimals then
182 Logging.xmlWarning(xmlFile, "Maximum number of animals reached! Maximum is '%d'!", maxAnimals)
183 spec.maxNumAnimals = maxAnimals
184 end
185
186 if GS_IS_MOBILE_VERSION then
187 spec.maxNumVisualAnimals = math.min(spec.maxNumVisualAnimals, 8) -- limit to 8 max on mobile
188 end
189
190 local maxNumVisualAnimals = xmlFile:getValue("placeable.husbandry.animals#maxNumVisualAnimals")
191 if maxNumVisualAnimals ~= nil then
192 if maxNumVisualAnimals > spec.maxNumAnimals then
193 maxNumVisualAnimals = spec.maxNumAnimals
194 end
195
196 if maxNumVisualAnimals > spec.maxNumVisualAnimals then
197 maxNumVisualAnimals = spec.maxNumVisualAnimals
198 end
199
200 spec.maxNumVisualAnimals = maxNumVisualAnimals
201 end
202
203 spec.clusterHusbandry = AnimalClusterHusbandry.new(self, animalTypeName, spec.maxNumVisualAnimals)
204
205 spec.clusterSystem = AnimalClusterSystem.new(self.isServer, self)
206 g_messageCenter:subscribe(AnimalClusterUpdateEvent, self.updatedClusters, self)
207
208
209 local animalLoadingTriggerNode = xmlFile:getValue("placeable.husbandry.animals.loadingTrigger#node", nil, self.components, self.i3dMappings)
210 if animalLoadingTriggerNode ~= nil then
211 spec.animalLoadingTrigger = AnimalLoadingTrigger.new(self.isServer, self.isClient)
212 if not spec.animalLoadingTrigger:load(animalLoadingTriggerNode, self) then
213 spec.animalLoadingTrigger:delete()
214 end
215 end
216
217 spec.deliveryAreas = {}
218 self.xmlFile:iterate("placeable.husbandry.animals.deliveryAreas.deliveryArea", function(_, key)
219 local area = {}
220 if self:loadDeliveryArea(self.xmlFile, key, area) then
221 table.insert(spec.deliveryAreas, area)
222 end
223 end)
224
225 spec.info = {title=g_i18n:getText("statistic_productivity"), text=""}
226
227 if not self.isServer or not g_isDevelopmentVersion then
228 removeConsoleCommand("gsHusbandryAddAnimals")
229 end
230end

onLoadedRideable

Description
Definition
onLoadedRideable()
Code
667function PlaceableHusbandryAnimals:onLoadedRideable(rideableVehicle, vehicleLoadState, arguments)
668 if rideableVehicle == nil then
669 return
670 end
671
672 if vehicleLoadState ~= VehicleLoadingUtil.VEHICLE_LOAD_OK then
673 rideableVehicle:delete()
674 return
675 end
676
677 local cluster = arguments.cluster
678 local newCluster = cluster:clone()
679 newCluster:changeNumAnimals(1)
680 rideableVehicle:setCluster(newCluster)
681 rideableVehicle:setPlayerToEnter(arguments.player)
682
683 local spec = self.spec_husbandryAnimals
684 cluster:changeNumAnimals(-1)
685 spec.clusterSystem:updateNow()
686end

onMissionStarted

Description
Definition
onMissionStarted()
Code
402function PlaceableHusbandryAnimals:onMissionStarted()
403 -- process animalsToLoad on onMissionStarted because dedi server is paused on start up and
404 -- therefore animals are first loaded if the first player joins. In this state husbandry is already synced with player
405 -- and no animals are visible for first player joining the server
406 self:updateVisualAnimals()
407end

onPeriodChanged

Description
Definition
onPeriodChanged()
Code
443function PlaceableHusbandryAnimals:onPeriodChanged()
444 if self.isServer then
445 local spec = self.spec_husbandryAnimals
446 local clusters = spec.clusterSystem:getClusters()
447
448 local totalNumAnimals = self:getNumOfAnimals()
449 local freeSlots = math.max(spec.maxNumAnimals - totalNumAnimals, 0)
450
451 for _, cluster in ipairs(clusters) do
452 cluster:onPeriodChanged()
453
454 local numNewAnimals = cluster:updateReproduction()
455 if numNewAnimals > 0 then
456 numNewAnimals = math.min(freeSlots, numNewAnimals)
457 if numNewAnimals > 0 then
458 local newCluster = g_currentMission.animalSystem:createClusterFromSubTypeIndex(cluster:getSubTypeIndex())
459 newCluster.numAnimals = numNewAnimals
460 freeSlots = freeSlots - numNewAnimals
461
462 spec.clusterSystem:addPendingAddCluster(newCluster)
463
464 local subType = g_currentMission.animalSystem:getSubTypeByIndex(cluster:getSubTypeIndex())
465 local animalType = g_currentMission.animalSystem:getTypeByIndex(subType.typeIndex)
466 if animalType.statsBreedingName ~= nil then
467 local stats = g_currentMission:farmStats(self:getOwnerFarmId())
468 stats:updateStats(animalType.statsBreedingName, newCluster.numAnimals)
469 end
470 end
471 end
472 end
473
474 self:raiseActive()
475 end
476end

onReadStream

Description
Definition
onReadStream()
Code
267function PlaceableHusbandryAnimals:onReadStream(streamId, connection)
268 local spec = self.spec_husbandryAnimals
269 spec.clusterSystem:readStream(streamId, connection)
270end

onUpdate

Description
Definition
onUpdate()
Code
295function PlaceableHusbandryAnimals:onUpdate(dt)
296 local spec = self.spec_husbandryAnimals
297 if self.isServer then
298 spec.clusterSystem:update(dt)
299 end
300
301 if spec.clusterHusbandry ~= nil then
302 spec.clusterHusbandry:update(dt)
303 end
304
305 if spec.updateVisuals then
306 self:updateVisualAnimals()
307 spec.updateVisuals = false
308 end
309
310 if spec.clusterHusbandry:getNeedsUpdate() then
311 self:raiseActive()
312 end
313end

onWriteStream

Description
Definition
onWriteStream()
Code
274function PlaceableHusbandryAnimals:onWriteStream(streamId, connection)
275 local spec = self.spec_husbandryAnimals
276 spec.clusterSystem:writeStream(streamId, connection)
277end

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
17function PlaceableHusbandryAnimals.prerequisitesPresent(specializations)
18 return SpecializationUtil.hasSpecialization(PlaceableHusbandry, specializations)
19end

registerEventListeners

Description
Definition
registerEventListeners()
Code
71function PlaceableHusbandryAnimals.registerEventListeners(placeableType)
72 SpecializationUtil.registerEventListener(placeableType, "onLoad", PlaceableHusbandryAnimals)
73 SpecializationUtil.registerEventListener(placeableType, "onDelete", PlaceableHusbandryAnimals)
74 SpecializationUtil.registerEventListener(placeableType, "onFinalizePlacement", PlaceableHusbandryAnimals)
75 SpecializationUtil.registerEventListener(placeableType, "onReadStream", PlaceableHusbandryAnimals)
76 SpecializationUtil.registerEventListener(placeableType, "onWriteStream", PlaceableHusbandryAnimals)
77 SpecializationUtil.registerEventListener(placeableType, "onUpdate", PlaceableHusbandryAnimals)
78 SpecializationUtil.registerEventListener(placeableType, "onPeriodChanged", PlaceableHusbandryAnimals)
79 SpecializationUtil.registerEventListener(placeableType, "onDayChanged", PlaceableHusbandryAnimals)
80end

registerEvents

Description
Definition
registerEvents()
Code
23function PlaceableHusbandryAnimals.registerEvents(placeableType)
24 SpecializationUtil.registerEvent(placeableType, "onHusbandryAnimalsCreated")
25 SpecializationUtil.registerEvent(placeableType, "onHusbandryAnimalsUpdate")
26end

registerFunctions

Description
Definition
registerFunctions()
Code
30function PlaceableHusbandryAnimals.registerFunctions(placeableType)
31 SpecializationUtil.registerFunction(placeableType, "onExternalNavigationMeshLoaded", PlaceableHusbandryAnimals.onExternalNavigationMeshLoaded)
32 SpecializationUtil.registerFunction(placeableType, "createHusbandry", PlaceableHusbandryAnimals.createHusbandry)
33 SpecializationUtil.registerFunction(placeableType, "updateVisualAnimals", PlaceableHusbandryAnimals.updateVisualAnimals)
34 SpecializationUtil.registerFunction(placeableType, "getNumOfFreeAnimalSlots", PlaceableHusbandryAnimals.getNumOfFreeAnimalSlots)
35 SpecializationUtil.registerFunction(placeableType, "getNumOfAnimals", PlaceableHusbandryAnimals.getNumOfAnimals)
36 SpecializationUtil.registerFunction(placeableType, "getMaxNumOfAnimals", PlaceableHusbandryAnimals.getMaxNumOfAnimals)
37 SpecializationUtil.registerFunction(placeableType, "getNumOfClusters", PlaceableHusbandryAnimals.getNumOfClusters)
38 SpecializationUtil.registerFunction(placeableType, "getSupportsAnimalSubType", PlaceableHusbandryAnimals.getSupportsAnimalSubType)
39 SpecializationUtil.registerFunction(placeableType, "getClusters", PlaceableHusbandryAnimals.getClusters)
40 SpecializationUtil.registerFunction(placeableType, "getCluster", PlaceableHusbandryAnimals.getCluster)
41 SpecializationUtil.registerFunction(placeableType, "getClusterById", PlaceableHusbandryAnimals.getClusterById)
42 SpecializationUtil.registerFunction(placeableType, "getClusterSystem", PlaceableHusbandryAnimals.getClusterSystem)
43 SpecializationUtil.registerFunction(placeableType, "getAnimalTypeIndex", PlaceableHusbandryAnimals.getAnimalTypeIndex)
44 SpecializationUtil.registerFunction(placeableType, "renameAnimal", PlaceableHusbandryAnimals.renameAnimal)
45 SpecializationUtil.registerFunction(placeableType, "addCluster", PlaceableHusbandryAnimals.addCluster)
46 SpecializationUtil.registerFunction(placeableType, "addAnimals", PlaceableHusbandryAnimals.addAnimals)
47 SpecializationUtil.registerFunction(placeableType, "updatedClusters", PlaceableHusbandryAnimals.updatedClusters)
48 SpecializationUtil.registerFunction(placeableType, "consoleCommandAddAnimals", PlaceableHusbandryAnimals.consoleCommandAddAnimals)
49 SpecializationUtil.registerFunction(placeableType, "getAnimalSupportsRiding", PlaceableHusbandryAnimals.getAnimalSupportsRiding)
50 SpecializationUtil.registerFunction(placeableType, "getAnimalCanBeRidden", PlaceableHusbandryAnimals.getAnimalCanBeRidden)
51 SpecializationUtil.registerFunction(placeableType, "startRiding", PlaceableHusbandryAnimals.startRiding)
52 SpecializationUtil.registerFunction(placeableType, "onLoadedRideable", PlaceableHusbandryAnimals.onLoadedRideable)
53 SpecializationUtil.registerFunction(placeableType, "getIsInAnimalDeliveryArea", PlaceableHusbandryAnimals.getIsInAnimalDeliveryArea)
54 SpecializationUtil.registerFunction(placeableType, "loadDeliveryArea", PlaceableHusbandryAnimals.loadDeliveryArea)
55end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
59function PlaceableHusbandryAnimals.registerOverwrittenFunctions(placeableType)
60 SpecializationUtil.registerOverwrittenFunction(placeableType, "getNeedDayChanged", PlaceableHusbandryAnimals.getNeedDayChanged)
61 SpecializationUtil.registerOverwrittenFunction(placeableType, "updateInfo", PlaceableHusbandryAnimals.updateInfo)
62 SpecializationUtil.registerOverwrittenFunction(placeableType, "updateOutput", PlaceableHusbandryAnimals.updateOutput)
63 SpecializationUtil.registerOverwrittenFunction(placeableType, "canBeSold", PlaceableHusbandryAnimals.canBeSold)
64 SpecializationUtil.registerOverwrittenFunction(placeableType, "getConditionInfos", PlaceableHusbandryAnimals.getConditionInfos)
65 SpecializationUtil.registerOverwrittenFunction(placeableType, "getAnimalInfos", PlaceableHusbandryAnimals.getAnimalInfos)
66 SpecializationUtil.registerOverwrittenFunction(placeableType, "getAnimalDescription", PlaceableHusbandryAnimals.getAnimalDescription)
67end

registerSavegameXMLPaths

Description
Definition
registerSavegameXMLPaths()
Code
105function PlaceableHusbandryAnimals.registerSavegameXMLPaths(schema, basePath)
106 schema:setXMLSpecializationType("Husbandry")
107 AnimalClusterSystem.registerSavegameXMLPaths(schema, basePath .. ".clusters")
108 schema:setXMLSpecializationType()
109end

registerXMLPaths

Description
Definition
registerXMLPaths()
Code
84function PlaceableHusbandryAnimals.registerXMLPaths(schema, basePath)
85 schema:setXMLSpecializationType("Husbandry")
86 basePath = basePath .. ".husbandry.animals"
87 schema:register(XMLValueType.NODE_INDEX, basePath .. ".navigation#rootNode", "Navigation mesh rootnode")
88 schema:register(XMLValueType.NODE_INDEX, basePath .. ".navigation#node", "Navigation mesh node")
89 schema:register(XMLValueType.STRING, basePath .. ".navigation#filename", "Filename for an external navigation mesh")
90 schema:register(XMLValueType.STRING, basePath .. ".navigation#nodePath", "Nodepath for an external navigation mesh")
91 schema:register(XMLValueType.STRING, basePath .. "#type", "Animal type")
92 schema:register(XMLValueType.STRING, basePath .. "#filename", "Animal configuration file")
93 schema:register(XMLValueType.FLOAT, basePath .. "#placementRaycastDistance", "Placement raycast distance", 2)
94 schema:register(XMLValueType.INT, basePath .. "#maxNumAnimals", "Max number of animals", 16)
95 schema:register(XMLValueType.INT, basePath .. "#maxNumVisualAnimals", "Max number of visual animals")
96 schema:register(XMLValueType.NODE_INDEX, basePath .. ".loadingTrigger#node", "Animal loading trigger")
97 schema:register(XMLValueType.NODE_INDEX, basePath .. ".deliveryAreas.deliveryArea(?)#startNode", "Animal delivery area start node")
98 schema:register(XMLValueType.NODE_INDEX, basePath .. ".deliveryAreas.deliveryArea(?)#widthNode", "Animal delivery area width node")
99 schema:register(XMLValueType.NODE_INDEX, basePath .. ".deliveryAreas.deliveryArea(?)#heightNode", "Animal delivery area height node")
100 schema:setXMLSpecializationType()
101end

renameAnimal

Description
Definition
renameAnimal()
Code
610function PlaceableHusbandryAnimals:renameAnimal(clusterId, name, noEventSend)
611 local spec = self.spec_husbandryAnimals
612 AnimalNameEvent.sendEvent(self, clusterId, name, noEventSend)
613
614 local cluster = spec.clusterSystem:getClusterById(clusterId)
615 if cluster ~= nil then
616 cluster:setName(name)
617 end
618end

saveToXMLFile

Description
Definition
saveToXMLFile()
Code
281function PlaceableHusbandryAnimals:saveToXMLFile(xmlFile, key, usedModNames)
282 local spec = self.spec_husbandryAnimals
283 spec.clusterSystem:saveToXMLFile(xmlFile, key .. ".clusters", usedModNames)
284end

startRiding

Description
Definition
startRiding()
Code
643function PlaceableHusbandryAnimals:startRiding(clusterId, player)
644 if not self.isServer then
645 g_client:getServerConnection():sendEvent(AnimalRidingEvent.new(self, clusterId, player))
646 else
647 local spec = self.spec_husbandryAnimals
648 local cluster = spec.clusterSystem:getClusterById(clusterId)
649 if cluster ~= nil then
650 local x, _, z, _, ry, _ = spec.clusterHusbandry:getAnimalPosition(clusterId)
651 if x ~= nil then
652 local farmId = self:getOwnerFarmId()
653 local filename = cluster:getRidableFilename()
654 local location = {x=x, z=z, yRot=ry}
655 local arguments = {
656 player = player,
657 cluster = cluster
658 }
659 VehicleLoadingUtil.loadVehicle(filename, location, true, 0, Vehicle.PROPERTY_STATE_OWNED, farmId, nil, nil, self.onLoadedRideable, self, arguments)
660 end
661 end
662 end
663end

updatedClusters

Description
Definition
updatedClusters()
Code
594function PlaceableHusbandryAnimals:updatedClusters(husbandry)
595 if husbandry == self then
596 local spec = self.spec_husbandryAnimals
597 local clusters = spec.clusterSystem:getClusters()
598
599 SpecializationUtil.raiseEvent(self, "onHusbandryAnimalsUpdate", clusters)
600
601 g_messageCenter:publish(MessageType.HUSBANDRY_ANIMALS_CHANGED, self)
602
603 spec.updateVisuals = true
604 self:raiseActive()
605 end
606end

updateInfo

Description
Definition
updateInfo()
Code
371function PlaceableHusbandryAnimals:updateInfo(superFunc, infoTable)
372 superFunc(self, infoTable)
373
374 local spec = self.spec_husbandryAnimals
375 local health = 0
376 local numAnimals = 0
377 local clusters = spec.clusterSystem:getClusters()
378 local numClusters = #clusters
379 if numClusters > 0 then
380 for _, cluster in ipairs(clusters) do
381 health = health + cluster.health
382 numAnimals = numAnimals + cluster.numAnimals
383 end
384
385 health = health / numClusters
386 end
387
388 spec.infoNumAnimals.text = string.format("%d", numAnimals)
389 spec.infoHealth.text = string.format("%d %%", health)
390 table.insert(infoTable, spec.infoNumAnimals)
391 table.insert(infoTable, spec.infoHealth)
392end

updateOutput

Description
Definition
updateOutput()
Code
427function PlaceableHusbandryAnimals:updateOutput(superFunc, foodFactor, productionFactor, globalProductionFactor)
428 if self.isServer then
429 local spec = self.spec_husbandryAnimals
430 local clusters = spec.clusterSystem:getClusters()
431 for _, cluster in ipairs(clusters) do
432 cluster:updateHealth(foodFactor)
433 end
434
435 self:raiseActive()
436 end
437
438 superFunc(self, foodFactor, productionFactor, globalProductionFactor)
439end

updateVisualAnimals

Description
Definition
updateVisualAnimals()
Code
411function PlaceableHusbandryAnimals:updateVisualAnimals()
412 local spec = self.spec_husbandryAnimals
413 local clusters = spec.clusterSystem:getClusters()
414 spec.clusterHusbandry:setClusters(clusters)
415 self:raiseActive()
416end