Script v1_7_1_0
- AI
- Animals
- Collections
- Contracts
- Debug
- Economy
- Elements
- EnvironmentalScore
- Errors
- Events
- GUI
- Handtools
- Hud
- I3d
- Input
- Jobs
- Maps
- Materials
- Misc
- Objects
- Parameters
- Placeables
- Placement
- Player
- Shop
- Sounds
- Specialization
- Specializations
- AIConveyorBelt
- AIDrivable
- AIFieldWorker
- AIImplement
- AIJobVehicle
- AIVehicle
- AIVehicleObstacle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- AutoLoader
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BaseMaterial
- BigBag
- BunkerSiloCompacter
- BunkerSiloInteractor
- CCTDrivable
- Combine
- ConnectionHoses
- ConveyorBelt
- Cover
- CrabSteering
- Crawlers
- CropSensor
- Cultivator
- Cutter
- Cylindered
- CylinderedFoldable
- Dashboard
- Dischargeable
- Drivable
- DynamicallyLoadedParts
- DynamicMountAttacher
- Enterable
- ExtendedAIVehicle
- ExtendedCombine
- ExtendedMotorized
- ExtendedMower
- ExtendedSowingMachine
- ExtendedSprayer
- ExtendedWearable
- FertilizingCultivator
- FertilizingSowingMachine
- FillTriggerVehicle
- FillUnit
- FillVolume
- Foldable
- FoliageBending
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- GroundAdjustedNodes
- GroundReference
- HeadlandAnimation
- Honk
- HookLiftContainer
- HookLiftTrailer
- IKChains
- InlineWrapper
- JigglingParts
- Leveler
- LicensePlates
- Lights
- LivestockTrailer
- Locomotive
- LogGrab
- ManureBarrel
- ManureSensor
- MixerWagon
- Motorized
- Mountable
- Mower
- Mulcher
- MultipleItemPurchase
- Pallet
- Pickup
- Pipe
- PlaceableAI
- PlaceableAnimatedObjects
- PlaceableBeehive
- PlaceableBeehivePalletSpa...
- PlaceableBunkerSilo
- PlaceableBuyingStation
- PlaceableCartridgePlayer
- PlaceableChargingStation
- PlaceableClearAreas
- PlaceableColorable
- PlaceableDeletedNodes
- PlaceableDoghouse
- PlaceableDynamicallyLoade...
- PlaceableFarmhouse
- PlaceableFence
- PlaceableFoliageAreas
- PlaceableGreenhouse
- PlaceableHighPressureWash...
- PlaceableHotspots
- PlaceableHusbandry
- PlaceableHusbandryAnimals
- PlaceableHusbandryFeeding...
- PlaceableHusbandryFence
- PlaceableHusbandryFood
- PlaceableHusbandryLiquidM...
- PlaceableHusbandryMilk
- PlaceableHusbandryPallets
- PlaceableHusbandryStraw
- PlaceableHusbandryWater
- PlaceableIncomePerHour
- PlaceableIndoorAreas
- PlaceableInfoTrigger
- PlaceableLeveling
- PlaceableLights
- PlaceableManureHeap
- PlaceablePlacement
- PlaceableProductionPoint
- PlaceableSellingStation
- PlaceableSilo
- PlaceableSiloExtension
- PlaceableSolarPanels
- PlaceableTipOcclusionArea...
- PlaceableTrainSystem
- PlaceableTriggerMarkers
- PlaceableVine
- PlaceableWardrobe
- PlaceableWeatherStation
- PlaceableWeighingStation
- PlaceableWindTurbine
- PlaceableWorkshop
- Plow
- PlowPacker
- PowerConsumer
- PowerTakeOffs
- PrecisionFarmingStatistic
- PushHandTool
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- Rideable
- RidgeMarker
- Roller
- Ropes
- RTKStation
- SaltSpreader
- SemiTrailerFront
- Shovel
- SlopeCompensation
- SmartAttach
- SoilSampler
- SowingMachine
- SpeedRotatingParts
- SplineVehicle
- Sprayer
- StonePicker
- StrawBlower
- StumpCutter
- SupportVehicle
- Suspensions
- Tedder
- TensionBeltObject
- TensionBelts
- TestAreas
- TipOccluder
- Trailer
- TreePlanter
- TreeSaplingPallet
- TreeSaw
- TurnOnVehicle
- VariableWorkWidth
- VehicleSettings
- VineCutter
- VineDetector
- VinePrepruner
- Washable
- WaterTrailer
- Wearable
- Weeder
- WeedSpotSpray
- Wheels
- WindBending
- Windrower
- Wipers
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkMode
- WorkParticles
- StateMachine
- Statistics
- Tasks
- Triggers
- Utils
- Vehicles
Engine v1_7_1_0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- general
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- NoteNode
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- VoiceChat
- XML
Foundation Reference
PlaceableHusbandryAnimals
DescriptionSpecialization for placeablesFunctions
- addAnimals
- addCluster
- canBeSold
- consoleCommandAddAnimals
- createHusbandry
- getAnimalCanBeRidden
- getAnimalDescription
- getAnimalInfos
- getAnimalSupportsRiding
- getAnimalTypeIndex
- getCluster
- getClusterById
- getClusters
- getClusterSystem
- getConditionInfos
- getIsInAnimalDeliveryArea
- getMaxNumOfAnimals
- getNeedDayChanged
- getNumOfAnimals
- getNumOfClusters
- getNumOfFreeAnimalSlots
- getSpecValueNumberAnimals
- getSupportsAnimalSubType
- initSpecialization
- loadDeliveryArea
- loadFromXMLFile
- loadSpecValueNumberAnimals
- onDayChanged
- onDelete
- onExternalNavigationMeshLoaded
- onFinalizePlacement
- onLoad
- onLoadedRideable
- onMissionStarted
- onPeriodChanged
- onReadStream
- onUpdate
- onWriteStream
- prerequisitesPresent
- registerEventListeners
- registerEvents
- registerFunctions
- registerOverwrittenFunctions
- registerSavegameXMLPaths
- registerXMLPaths
- renameAnimal
- saveToXMLFile
- startRiding
- updatedClusters
- updateInfo
- updateOutput
- updateVisualAnimals
addAnimals
DescriptionDefinitionaddAnimals()Code
568 | function 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 |
583 | end |
addCluster
DescriptionDefinitionaddCluster()Code
558 | function PlaceableHusbandryAnimals:addCluster(cluster) |
559 | if cluster ~= nil then |
560 | local spec = self.spec_husbandryAnimals |
561 | spec.clusterSystem:addPendingAddCluster(cluster) |
562 | self:raiseActive() |
563 | end |
564 | end |
canBeSold
DescriptionDefinitioncanBeSold()Code
789 | function PlaceableHusbandryAnimals:canBeSold(superFunc) |
790 | if self:getNumOfAnimals() > 0 then |
791 | return false, g_i18n:getText("info_husbandryNotEmpty") |
792 | end |
793 | |
794 | return superFunc(self) |
795 | end |
consoleCommandAddAnimals
DescriptionDefinitionconsoleCommandAddAnimals()Code
837 | function 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 |
892 | end |
createHusbandry
DescriptionDefinitioncreateHusbandry()Code
337 | function 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) |
367 | end |
getAnimalCanBeRidden
DescriptionDefinitiongetAnimalCanBeRidden()Code
637 | function PlaceableHusbandryAnimals:getAnimalCanBeRidden(clusterId) |
638 | return g_currentMission.husbandrySystem:getCanAddRideable(self:getOwnerFarmId()) |
639 | end |
getAnimalDescription
DescriptionDefinitiongetAnimalDescription()Code
827 | function 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 |
833 | end |
getAnimalInfos
DescriptionDefinitiongetAnimalInfos()Code
817 | function PlaceableHusbandryAnimals:getAnimalInfos(superFunc, cluster) |
818 | local infos = superFunc(self) |
819 | |
820 | cluster:addInfos(infos) |
821 | |
822 | return infos |
823 | end |
getAnimalSupportsRiding
DescriptionDefinitiongetAnimalSupportsRiding()Code
622 | function 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 |
633 | end |
getAnimalTypeIndex
DescriptionDefinitiongetAnimalTypeIndex()Code
420 | function PlaceableHusbandryAnimals:getAnimalTypeIndex() |
421 | local spec = self.spec_husbandryAnimals |
422 | return spec.animalTypeIndex |
423 | end |
getCluster
DescriptionDefinitiongetCluster()Code
544 | function PlaceableHusbandryAnimals:getCluster(index) |
545 | local spec = self.spec_husbandryAnimals |
546 | return spec.clusterSystem:getCluster(index) |
547 | end |
getClusterById
DescriptionDefinitiongetClusterById()Code
551 | function PlaceableHusbandryAnimals:getClusterById(id) |
552 | local spec = self.spec_husbandryAnimals |
553 | return spec.clusterSystem:getClusterById(id) |
554 | end |
getClusters
DescriptionDefinitiongetClusters()Code
537 | function PlaceableHusbandryAnimals:getClusters() |
538 | local spec = self.spec_husbandryAnimals |
539 | return spec.clusterSystem:getClusters() |
540 | end |
getClusterSystem
DescriptionDefinitiongetClusterSystem()Code
587 | function PlaceableHusbandryAnimals:getClusterSystem() |
588 | local spec = self.spec_husbandryAnimals |
589 | return spec.clusterSystem |
590 | end |
getConditionInfos
DescriptionDefinitiongetConditionInfos()Code
799 | function 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 |
813 | end |
getIsInAnimalDeliveryArea
DescriptionDefinitiongetIsInAnimalDeliveryArea()Code
718 | function 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 | |
745 | end |
getMaxNumOfAnimals
DescriptionDefinitiongetMaxNumOfAnimals()Code
505 | function PlaceableHusbandryAnimals:getMaxNumOfAnimals() |
506 | local spec = self.spec_husbandryAnimals |
507 | return spec.maxNumAnimals |
508 | end |
getNeedDayChanged
DescriptionDefinitiongetNeedDayChanged()Code
396 | function PlaceableHusbandryAnimals:getNeedDayChanged(superFunc) |
397 | return true |
398 | end |
getNumOfAnimals
DescriptionDefinitiongetNumOfAnimals()Code
492 | function 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 |
501 | end |
getNumOfClusters
DescriptionDefinitiongetNumOfClusters()Code
529 | function PlaceableHusbandryAnimals:getNumOfClusters() |
530 | local spec = self.spec_husbandryAnimals |
531 | local clusters = spec.clusterSystem:getClusters() |
532 | return #clusters |
533 | end |
getNumOfFreeAnimalSlots
DescriptionDefinitiongetNumOfFreeAnimalSlots()Code
512 | function PlaceableHusbandryAnimals:getNumOfFreeAnimalSlots() |
513 | local spec = self.spec_husbandryAnimals |
514 | local totalNumAnimals = self:getNumOfAnimals() |
515 | return math.max(spec.maxNumAnimals - totalNumAnimals, 0) |
516 | end |
getSpecValueNumberAnimals
DescriptionDefinitiongetSpecValueNumberAnimals()Code
763 | function 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 |
785 | end |
getSupportsAnimalSubType
DescriptionDefinitiongetSupportsAnimalSubType()Code
520 | function 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 |
525 | end |
initSpecialization
DescriptionDefinitioninitSpecialization()Code
113 | function 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 |
119 | end |
loadDeliveryArea
DescriptionDefinitionloadDeliveryArea()Code
690 | function 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 |
714 | end |
loadFromXMLFile
DescriptionDefinitionloadFromXMLFile()Code
288 | function PlaceableHusbandryAnimals:loadFromXMLFile(xmlFile, key) |
289 | local spec = self.spec_husbandryAnimals |
290 | spec.clusterSystem:loadFromXMLFile(xmlFile, key .. ".clusters") |
291 | end |
loadSpecValueNumberAnimals
DescriptionDefinitionloadSpecValueNumberAnimals()Code
749 | function 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 |
759 | end |
onDayChanged
DescriptionDefinitiononDayChanged()Code
480 | function 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 |
488 | end |
onDelete
DescriptionDefinitiononDelete()Code
234 | function 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) |
254 | end |
onExternalNavigationMeshLoaded
DescriptionDefinitiononExternalNavigationMeshLoaded()Code
317 | function 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) |
333 | end |
onFinalizePlacement
DescriptionDefinitiononFinalizePlacement()Code
258 | function PlaceableHusbandryAnimals:onFinalizePlacement() |
259 | -- load navigation mesh |
260 | self:createHusbandry() |
261 | |
262 | g_currentMission:registerObjectToCallOnMissionStart(self) |
263 | end |
onLoad
DescriptionDefinitiononLoad()Code
123 | function 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 |
230 | end |
onLoadedRideable
DescriptionDefinitiononLoadedRideable()Code
667 | function 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() |
686 | end |
onMissionStarted
DescriptionDefinitiononMissionStarted()Code
402 | function 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() |
407 | end |
onPeriodChanged
DescriptionDefinitiononPeriodChanged()Code
443 | function 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 |
476 | end |
onReadStream
DescriptionDefinitiononReadStream()Code
267 | function PlaceableHusbandryAnimals:onReadStream(streamId, connection) |
268 | local spec = self.spec_husbandryAnimals |
269 | spec.clusterSystem:readStream(streamId, connection) |
270 | end |
onUpdate
DescriptionDefinitiononUpdate()Code
295 | function 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 |
313 | end |
onWriteStream
DescriptionDefinitiononWriteStream()Code
274 | function PlaceableHusbandryAnimals:onWriteStream(streamId, connection) |
275 | local spec = self.spec_husbandryAnimals |
276 | spec.clusterSystem:writeStream(streamId, connection) |
277 | end |
prerequisitesPresent
DescriptionChecks if all prerequisite specializations are loadedDefinition
prerequisitesPresent(table specializations)Arguments
table | specializations | specializations |
boolean | hasPrerequisite | true if all prerequisite specializations are loaded |
17 | function PlaceableHusbandryAnimals.prerequisitesPresent(specializations) |
18 | return SpecializationUtil.hasSpecialization(PlaceableHusbandry, specializations) |
19 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
71 | function 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) |
80 | end |
registerEvents
DescriptionDefinitionregisterEvents()Code
23 | function PlaceableHusbandryAnimals.registerEvents(placeableType) |
24 | SpecializationUtil.registerEvent(placeableType, "onHusbandryAnimalsCreated") |
25 | SpecializationUtil.registerEvent(placeableType, "onHusbandryAnimalsUpdate") |
26 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
30 | function 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) |
55 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
59 | function 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) |
67 | end |
registerSavegameXMLPaths
DescriptionDefinitionregisterSavegameXMLPaths()Code
105 | function PlaceableHusbandryAnimals.registerSavegameXMLPaths(schema, basePath) |
106 | schema:setXMLSpecializationType("Husbandry") |
107 | AnimalClusterSystem.registerSavegameXMLPaths(schema, basePath .. ".clusters") |
108 | schema:setXMLSpecializationType() |
109 | end |
registerXMLPaths
DescriptionDefinitionregisterXMLPaths()Code
84 | function 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() |
101 | end |
renameAnimal
DescriptionDefinitionrenameAnimal()Code
610 | function 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 |
618 | end |
saveToXMLFile
DescriptionDefinitionsaveToXMLFile()Code
281 | function PlaceableHusbandryAnimals:saveToXMLFile(xmlFile, key, usedModNames) |
282 | local spec = self.spec_husbandryAnimals |
283 | spec.clusterSystem:saveToXMLFile(xmlFile, key .. ".clusters", usedModNames) |
284 | end |
startRiding
DescriptionDefinitionstartRiding()Code
643 | function 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 |
663 | end |
updatedClusters
DescriptionDefinitionupdatedClusters()Code
594 | function 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 |
606 | end |
updateInfo
DescriptionDefinitionupdateInfo()Code
371 | function 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) |
392 | end |
updateOutput
DescriptionDefinitionupdateOutput()Code
427 | function 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) |
439 | end |
updateVisualAnimals
DescriptionDefinitionupdateVisualAnimals()Code
411 | function PlaceableHusbandryAnimals:updateVisualAnimals() |
412 | local spec = self.spec_husbandryAnimals |
413 | local clusters = spec.clusterSystem:getClusters() |
414 | spec.clusterHusbandry:setClusters(clusters) |
415 | self:raiseActive() |
416 | end |