Advertisement
Bitfogav

Untitled

Feb 13th, 2025
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.18 KB | Gaming | 0 0
  1. ---Checks if all prerequisite specializations are loaded
  2. -- @param table specializations specializations
  3. -- @return boolean hasPrerequisite true if all prerequisite specializations are loaded
  4. function PlaceableHusbandryAnimals.prerequisitesPresent(specializations)
  5.     return SpecializationUtil.hasSpecialization(PlaceableHusbandry, specializations)
  6. end
  7.  
  8.  
  9. ---
  10. function PlaceableHusbandryAnimals.registerEvents(placeableType)
  11.     SpecializationUtil.registerEvent(placeableType, "onHusbandryAnimalsCreated")
  12.     SpecializationUtil.registerEvent(placeableType, "onHusbandryAnimalsUpdate")
  13. end
  14.  
  15.  
  16. ---
  17. function PlaceableHusbandryAnimals.registerFunctions(placeableType)
  18.     SpecializationUtil.registerFunction(placeableType, "onExternalNavigationMeshLoaded", PlaceableHusbandryAnimals.onExternalNavigationMeshLoaded)
  19.     SpecializationUtil.registerFunction(placeableType, "createNavigationMeshFromContour", PlaceableHusbandryAnimals.createNavigationMeshFromContour)
  20.     SpecializationUtil.registerFunction(placeableType, "createNavigationMesh", PlaceableHusbandryAnimals.createNavigationMesh)
  21.     SpecializationUtil.registerFunction(placeableType, "setMaxNumAnimals", PlaceableHusbandryAnimals.setMaxNumAnimals)
  22.     SpecializationUtil.registerFunction(placeableType, "createHusbandry", PlaceableHusbandryAnimals.createHusbandry)
  23.     SpecializationUtil.registerFunction(placeableType, "updateVisualAnimals", PlaceableHusbandryAnimals.updateVisualAnimals)
  24.     SpecializationUtil.registerFunction(placeableType, "getNumOfFreeAnimalSlots", PlaceableHusbandryAnimals.getNumOfFreeAnimalSlots)
  25.     SpecializationUtil.registerFunction(placeableType, "getNumOfAnimals", PlaceableHusbandryAnimals.getNumOfAnimals)
  26.     SpecializationUtil.registerFunction(placeableType, "getMaxNumOfAnimals", PlaceableHusbandryAnimals.getMaxNumOfAnimals)
  27.     SpecializationUtil.registerFunction(placeableType, "getNumOfClusters", PlaceableHusbandryAnimals.getNumOfClusters)
  28.     SpecializationUtil.registerFunction(placeableType, "getSupportsAnimalSubType", PlaceableHusbandryAnimals.getSupportsAnimalSubType)
  29.     SpecializationUtil.registerFunction(placeableType, "getClusters", PlaceableHusbandryAnimals.getClusters)
  30.     SpecializationUtil.registerFunction(placeableType, "getCluster", PlaceableHusbandryAnimals.getCluster)
  31.     SpecializationUtil.registerFunction(placeableType, "getClusterById", PlaceableHusbandryAnimals.getClusterById)
  32.     SpecializationUtil.registerFunction(placeableType, "getClusterSystem", PlaceableHusbandryAnimals.getClusterSystem)
  33.     SpecializationUtil.registerFunction(placeableType, "getAnimalTypeIndex", PlaceableHusbandryAnimals.getAnimalTypeIndex)
  34.     SpecializationUtil.registerFunction(placeableType, "renameAnimal", PlaceableHusbandryAnimals.renameAnimal)
  35.     SpecializationUtil.registerFunction(placeableType, "addCluster", PlaceableHusbandryAnimals.addCluster)
  36.     SpecializationUtil.registerFunction(placeableType, "addAnimals", PlaceableHusbandryAnimals.addAnimals)
  37.     SpecializationUtil.registerFunction(placeableType, "updatedClusters", PlaceableHusbandryAnimals.updatedClusters)
  38.     SpecializationUtil.registerFunction(placeableType, "consoleCommandAddAnimals", PlaceableHusbandryAnimals.consoleCommandAddAnimals)
  39.     SpecializationUtil.registerFunction(placeableType, "getAnimalSupportsRiding", PlaceableHusbandryAnimals.getAnimalSupportsRiding)
  40.     SpecializationUtil.registerFunction(placeableType, "getAnimalCanBeRidden", PlaceableHusbandryAnimals.getAnimalCanBeRidden)
  41.     SpecializationUtil.registerFunction(placeableType, "startRiding", PlaceableHusbandryAnimals.startRiding)
  42.     SpecializationUtil.registerFunction(placeableType, "onLoadedRideable", PlaceableHusbandryAnimals.onLoadedRideable)
  43.     SpecializationUtil.registerFunction(placeableType, "getIsInAnimalDeliveryArea", PlaceableHusbandryAnimals.getIsInAnimalDeliveryArea)
  44.     SpecializationUtil.registerFunction(placeableType, "loadDeliveryArea", PlaceableHusbandryAnimals.loadDeliveryArea)
  45.     SpecializationUtil.registerFunction(placeableType, "getOutdoorContourPolygon", PlaceableHusbandryAnimals.getOutdoorContourPolygon)
  46.     SpecializationUtil.registerFunction(placeableType, "createNavigationMeshPlacementCollision", PlaceableHusbandryAnimals.createNavigationMeshPlacementCollision)
  47.     SpecializationUtil.registerFunction(placeableType, "deleteNavigationMeshPlacementCollision", PlaceableHusbandryAnimals.deleteNavigationMeshPlacementCollision)
  48. end
  49.  
  50.  
  51. ---
  52. function PlaceableHusbandryAnimals.registerOverwrittenFunctions(placeableType)
  53.     SpecializationUtil.registerOverwrittenFunction(placeableType, "getNeedDayChanged", PlaceableHusbandryAnimals.getNeedDayChanged)
  54.     SpecializationUtil.registerOverwrittenFunction(placeableType, "updateInfo", PlaceableHusbandryAnimals.updateInfo)
  55.     SpecializationUtil.registerOverwrittenFunction(placeableType, "updateOutput", PlaceableHusbandryAnimals.updateOutput)
  56.     SpecializationUtil.registerOverwrittenFunction(placeableType, "canBeSold", PlaceableHusbandryAnimals.canBeSold)
  57.     SpecializationUtil.registerOverwrittenFunction(placeableType, "getConditionInfos", PlaceableHusbandryAnimals.getConditionInfos)
  58.     SpecializationUtil.registerOverwrittenFunction(placeableType, "getAnimalInfos", PlaceableHusbandryAnimals.getAnimalInfos)
  59.     SpecializationUtil.registerOverwrittenFunction(placeableType, "getAnimalDescription", PlaceableHusbandryAnimals.getAnimalDescription)
  60. end
  61.  
  62.  
  63. ---
  64. function PlaceableHusbandryAnimals.registerEventListeners(placeableType)
  65.     SpecializationUtil.registerEventListener(placeableType, "onLoad", PlaceableHusbandryAnimals)
  66.     SpecializationUtil.registerEventListener(placeableType, "onDelete", PlaceableHusbandryAnimals)
  67.     SpecializationUtil.registerEventListener(placeableType, "onFinalizePlacement", PlaceableHusbandryAnimals)
  68.     SpecializationUtil.registerEventListener(placeableType, "onReadStream", PlaceableHusbandryAnimals)
  69.     SpecializationUtil.registerEventListener(placeableType, "onWriteStream", PlaceableHusbandryAnimals)
  70.     SpecializationUtil.registerEventListener(placeableType, "onUpdate", PlaceableHusbandryAnimals)
  71.     SpecializationUtil.registerEventListener(placeableType, "onPeriodChanged", PlaceableHusbandryAnimals)
  72.     SpecializationUtil.registerEventListener(placeableType, "onDayChanged", PlaceableHusbandryAnimals)
  73. end
  74.  
  75.  
  76. ---
  77. function PlaceableHusbandryAnimals.registerXMLPaths(schema, basePath)
  78.     schema:setXMLSpecializationType("Husbandry")
  79.     basePath = basePath .. ".husbandry.animals"
  80.     schema:register(XMLValueType.NODE_INDEX, basePath .. ".navigation#rootNode", "Navigation mesh rootnode")
  81.     schema:register(XMLValueType.NODE_INDEX, basePath .. ".navigation#node", "Navigation mesh node")
  82.     schema:register(XMLValueType.NODE_INDEX, basePath .. ".navigation#shape", "Shape to generate navigation mesh from")
  83.     schema:register(XMLValueType.STRING, basePath .. ".navigation#filename", "Filename for an external navigation mesh")
  84.     schema:register(XMLValueType.STRING, basePath .. ".navigation#nodePath", "Nodepath for an external navigation mesh")
  85.     schema:register(XMLValueType.STRING, basePath .. "#type", "Animal type")
  86.     schema:register(XMLValueType.STRING, basePath .. "#filename", "Animal configuration file")
  87.     schema:register(XMLValueType.FLOAT, basePath .. "#placementRaycastDistance", "Placement raycast distance", 2)
  88.     schema:register(XMLValueType.INT, basePath .. "#maxNumAnimals", "Max number of animals", 16)
  89.     schema:register(XMLValueType.INT, basePath .. "#baseMaxNumAnimals", "Base max number of animals without outoor area", 16)
  90.     schema:register(XMLValueType.INT, basePath .. "#sqmPerAnimal", "Square meter need per animal")
  91.     schema:register(XMLValueType.INT, basePath .. "#maxNumVisualAnimals", "Max number of visual animals")
  92.     schema:register(XMLValueType.NODE_INDEX, basePath .. ".loadingTrigger#node", "Animal loading trigger")
  93.     schema:register(XMLValueType.NODE_INDEX, basePath .. ".deliveryAreas.deliveryArea(?)#startNode", "Animal delivery area start node")
  94.     schema:register(XMLValueType.NODE_INDEX, basePath .. ".deliveryAreas.deliveryArea(?)#widthNode", "Animal delivery area width node")
  95.     schema:register(XMLValueType.NODE_INDEX, basePath .. ".deliveryAreas.deliveryArea(?)#heightNode", "Animal delivery area height node")
  96.     schema:setXMLSpecializationType()
  97. end
  98.  
  99.  
  100. ---
  101. function PlaceableHusbandryAnimals.registerSavegameXMLPaths(schema, basePath)
  102.     schema:setXMLSpecializationType("Husbandry")
  103.     AnimalClusterSystem.registerSavegameXMLPaths(schema, basePath .. ".clusters")
  104.     schema:setXMLSpecializationType()
  105. end
  106.  
  107.  
  108. ---
  109. function PlaceableHusbandryAnimals.initSpecialization()
  110.     g_storeManager:addSpecType("numberAnimals", "shopListAttributeIconCapacity", PlaceableHusbandryAnimals.loadSpecValueNumberAnimals, PlaceableHusbandryAnimals.getSpecValueNumberAnimals, StoreSpecies.PLACEABLE)
  111.  
  112.     if g_isDevelopmentVersion then
  113.         addConsoleCommand("gsHusbandryAddAnimals", "Add or remove animals from husbandry where player is currently located", "consoleCommandAddAnimals", PlaceableHusbandryAnimals, "numAnimals; [subTypeIndex]")
  114.         addConsoleCommand("gsHusbandryDebugToggle", "Toggle husbandry debug mode", "consoleCommandToggleDebug", PlaceableHusbandryAnimals)
  115.     end
  116. end
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126. ---
  127. function PlaceableHusbandryAnimals:onLoad(savegame)
  128.     local spec = self.spec_husbandryAnimals
  129.     local xmlFile = self.xmlFile
  130.  
  131.     spec.infoHealth = {title=g_i18n:getText("ui_horseHealth"), text=""}
  132.     spec.infoNumAnimals = {title=g_i18n:getText("ui_numAnimals"), text=""}
  133.     spec.updateVisuals = false
  134.  
  135.     local animalTypeName = xmlFile:getValue("placeable.husbandry.animals#type")
  136.     if animalTypeName == nil then
  137.         Logging.xmlError(xmlFile, "Missing animal type!")
  138.         self:setLoadingState(PlaceableLoadingState.ERROR)
  139.         return
  140.     end
  141.  
  142.     local mission = g_currentMission
  143.     spec.animalType = mission.animalSystem:getTypeByName(animalTypeName)
  144.     if spec.animalType == nil then
  145.         Logging.xmlError(xmlFile, "Animal type '%s' not found!", animalTypeName)
  146.         self:setLoadingState(PlaceableLoadingState.ERROR)
  147.         return
  148.     end
  149.  
  150.     spec.animalTypeIndex = spec.animalType.typeIndex
  151.  
  152.     spec.navigationMeshRootNode = xmlFile:getValue("placeable.husbandry.animals.navigation#rootNode", nil, self.components, self.i3dMappings)
  153.     spec.navigationMesh = xmlFile:getValue("placeable.husbandry.animals.navigation#node", nil, self.components, self.i3dMappings)
  154.     local navigationMeshShape = xmlFile:getValue("placeable.husbandry.animals.navigation#shape", nil, self.components, self.i3dMappings)
  155.     if navigationMeshShape ~= nil then
  156.         local navMeshShapeValid = true
  157.         if not getHasClassId(navigationMeshShape, ClassIds.SHAPE) then
  158.             Logging.xmlError(xmlFile, "Given navigation shape %q at %q is not of type 'SHAPE'", getName(navigationMeshShape), "placeable.husbandry.animals.navigation#shape")
  159.             navMeshShapeValid = false
  160.         end
  161.  
  162.         if getHasClassId(navigationMeshShape, ClassIds.NAVIGATION_MESH) then
  163.             Logging.xmlError(xmlFile, "Given navigation shape %q at %q is a navigation mesh instead of a regular shape", getName(navigationMeshShape), "placeable.husbandry.animals.navigation#shape")
  164.             navMeshShapeValid = false
  165.         end
  166.  
  167.         if navMeshShapeValid and not getShapeIsCPUMesh(navigationMeshShape) then
  168.             Logging.xmlError(xmlFile, "Given navigation shape %q at %q is missing the 'CPU Mesh' flag", getName(navigationMeshShape), "placeable.husbandry.animals.navigation#shape")
  169.             navMeshShapeValid = false
  170.         end
  171.  
  172.         if navMeshShapeValid then
  173.             setIsNonRenderable(navigationMeshShape, true)
  174.             spec.navigationMeshShape = navigationMeshShape
  175.         end
  176.     end
  177.     local navigationMeshFilename = xmlFile:getValue("placeable.husbandry.animals.navigation#filename", nil)
  178.     if navigationMeshFilename ~= nil then
  179.         navigationMeshFilename = Utils.getFilename(navigationMeshFilename, self.baseDirectory)
  180.         local loadingTask = self:createLoadingTask(spec)
  181.         spec.navigationMeshNodePath = xmlFile:getValue("placeable.husbandry.animals.navigation#nodePath", "0")
  182.  
  183.         local arguments = {
  184.             loadingTask = loadingTask
  185.         }
  186.         spec.sharedLoadRequestId = g_i3DManager:loadSharedI3DFileAsync(navigationMeshFilename, true, false, self.onExternalNavigationMeshLoaded, self, arguments)
  187.     end
  188.  
  189.     -- polygon for the nav mesh area defined by the fence outline, excluding the area defined by the navigationMeshShape
  190.     spec.outdoorContourPolygon = nil
  191.  
  192.     spec.placementRaycastDistance = xmlFile:getValue("placeable.husbandry.animals#placementRaycastDistance", 10.0)
  193.     spec.sqmPerAnimal = self.xmlFile:getValue("placeable.husbandry.animals#sqmPerAnimal", 100)
  194.     spec.configMaxNumAnimals = xmlFile:getValue("placeable.husbandry.animals#maxNumAnimals", 16)
  195.     spec.baseMaxNumAnimals = self.xmlFile:getValue("placeable.husbandry.animals#baseMaxNumAnimals", spec.configMaxNumAnimals)
  196.     spec.configMaxNumVisualAnimals = self.xmlFile:getValue("placeable.husbandry.animals#maxNumVisualAnimals")
  197.  
  198.     spec.clusterHusbandry = AnimalClusterHusbandry.new(self, animalTypeName, 0) --spec.maxNumVisualAnimals)
  199.  
  200.     spec.clusterSystem = AnimalClusterSystem.new(self.isServer, self)
  201.     g_messageCenter:subscribe(AnimalClusterUpdateEvent, self.updatedClusters, self)
  202.  
  203.     local animalLoadingTriggerNode = xmlFile:getValue("placeable.husbandry.animals.loadingTrigger#node", nil, self.components, self.i3dMappings)
  204.     if animalLoadingTriggerNode ~= nil then
  205.         spec.animalLoadingTrigger = AnimalLoadingTrigger.new(self.isServer, self.isClient)
  206.         if not spec.animalLoadingTrigger:load(animalLoadingTriggerNode, self) then
  207.             spec.animalLoadingTrigger:delete()
  208.         end
  209.     end
  210.  
  211.     spec.deliveryAreas = {}
  212.     self.xmlFile:iterate("placeable.husbandry.animals.deliveryAreas.deliveryArea", function(_, key)
  213.         local area = {}
  214.         if self:loadDeliveryArea(self.xmlFile, key, area) then
  215.             table.insert(spec.deliveryAreas, area)
  216.         end
  217.     end)
  218.  
  219.     spec.info = {title=g_i18n:getText("statistic_productivity"), text=""}
  220.  
  221.     if not self.isServer or not g_isDevelopmentVersion then
  222.         removeConsoleCommand("gsHusbandryAddAnimals")
  223.     end
  224. end
  225.  
  226.  
  227. ---
  228. function PlaceableHusbandryAnimals:onDelete()
  229.     local spec = self.spec_husbandryAnimals
  230.  
  231.     g_messageCenter:unsubscribe(AnimalClusterUpdateEvent, self)
  232.     g_messageCenter:unsubscribe(MessageType.CURRENT_MISSION_START, self)
  233.  
  234.     self:deleteNavigationMeshPlacementCollision()
  235.  
  236.     if spec.clusterHusbandry ~= nil then
  237.         local mission = g_currentMission
  238.         mission.husbandrySystem:removeClusterHusbandry(spec.clusterHusbandry)
  239.         spec.clusterHusbandry:delete()
  240.         spec.clusterHusbandry = nil
  241.     end
  242.     if spec.animalLoadingTrigger ~= nil then
  243.         spec.animalLoadingTrigger:delete()
  244.         spec.animalLoadingTrigger = nil
  245.     end
  246.  
  247.     if spec.sharedLoadRequestId ~= nil then
  248.         g_i3DManager:releaseSharedI3DFile(spec.sharedLoadRequestId)
  249.     end
  250. end
  251.  
  252.  
  253. ---
  254. function PlaceableHusbandryAnimals:onFinalizePlacement()
  255.     self:createNavigationMesh()
  256.  
  257.     if self.isLoadedFromSavegame then
  258.         g_messageCenter:subscribeOneshot(MessageType.CURRENT_MISSION_START, PlaceableHusbandryAnimals.onMissionStarted, self)
  259.     end
  260. end
  261.  
  262.  
  263. ---
  264. function PlaceableHusbandryAnimals:onReadStream(streamId, connection)
  265.     local spec = self.spec_husbandryAnimals
  266.     spec.clusterSystem:readStream(streamId, connection)
  267. end
  268.  
  269.  
  270. ---
  271. function PlaceableHusbandryAnimals:onWriteStream(streamId, connection)
  272.     local spec = self.spec_husbandryAnimals
  273.     spec.clusterSystem:writeStream(streamId, connection)
  274. end
  275.  
  276.  
  277. ---
  278. function PlaceableHusbandryAnimals:saveToXMLFile(xmlFile, key, usedModNames)
  279.     local spec = self.spec_husbandryAnimals
  280.     spec.clusterSystem:saveToXMLFile(xmlFile, key .. ".clusters", usedModNames)
  281. end
  282.  
  283.  
  284. ---
  285. function PlaceableHusbandryAnimals:loadFromXMLFile(xmlFile, key)
  286.     local spec = self.spec_husbandryAnimals
  287.     spec.clusterSystem:loadFromXMLFile(xmlFile, key .. ".clusters")
  288. end
  289.  
  290.  
  291. ---
  292. function PlaceableHusbandryAnimals:onUpdate(dt)
  293.     local spec = self.spec_husbandryAnimals
  294.     if self.isServer then
  295.         spec.clusterSystem:update(dt)
  296.     end
  297.  
  298.     if spec.clusterHusbandry ~= nil then
  299.         spec.clusterHusbandry:update(dt)
  300.     end
  301.  
  302.     if spec.updateVisuals then
  303.         self:updateVisualAnimals()
  304.         spec.updateVisuals = false
  305.     end
  306.  
  307.     if spec.clusterHusbandry:getNeedsUpdate() then
  308.         self:raiseActive()
  309.     end
  310. end
  311.  
  312.  
  313. ---
  314. function PlaceableHusbandryAnimals:onExternalNavigationMeshLoaded(node, failedReason, args)
  315.     local spec = self.spec_husbandryAnimals
  316.  
  317.     local loadingTask = args.loadingTask
  318.  
  319.     if node == 0 or node == nil then
  320.         self:finishLoadingTask(loadingTask)
  321.         Logging.error("Missing navigation mesh in external navigation mesh file!")
  322.         return
  323.     end
  324.  
  325.     if spec.navigationMeshRootNode ~= nil then
  326.         spec.navigationMesh = I3DUtil.indexToObject(node, spec.navigationMeshNodePath)
  327.         link(spec.navigationMeshRootNode, spec.navigationMesh)
  328.     end
  329.     delete(node)
  330.  
  331.     self:finishLoadingTask(loadingTask)
  332. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement