Planet Zoo - Random Animals
Click here for the mod on Nexus Mods ;
Here for the code on GitHub ;
Or here for the YouTube video .
Picking your own animals for your zoo can be kinda boring. So I made a mod which randomizes an animal in your zoo at random intervals.
This mod uses ACSE, which is a tool that allows you to more easily make mods for Planet Zoo.
To create this mod we need to edit a zoo manager file. In the Activate function we create a table that contains all of the species that are available to the player. By doing this in the Activate function we only have to do it once, thus preventing a lot of lag. The final code for this looks as follows:
RandomAnimalsManager.Activate = function(self)
api.debug.Trace("RandomAnimalsManager:Activate()")
self.tAnimalsToSpawn = {}
local cPSInstance = ((api.database).GetPreparedStatementInstance) ("Animals", "GetReadyAnimals")
if cPSInstance ~= nil then
((api.database).BindComplete)(cPSInstance)
;
((api.database).Step)(cPSInstance)
local tResult = ((api.database).GetAllResults)(cPSInstance, false)
for _,tData in pairs(tResult) do
if ((api.content).IsDLCOwned)(tData[2]) then
-- api.debug.Trace(tData[1])
(table.insert)(self.tAnimalsToSpawn, tData[1])
-- api.debug.Trace("Hello")
end
end
end
self.iNumberOfAnimals = 0
for k,v in pairs(self.tAnimalsToSpawn) do
self.iNumberOfAnimals = self.iNumberOfAnimals + 1
end
api.debug.Trace(self.iNumberOfAnimals)
end
The code to actually replace the animals is located int the Advance function. This means that it gets called at every game tick. Our mod should only work in Sandbox, so that is the first thing we need to check for.
The math.random(1, 7500) call influences how often animals are replaced. How likely this should be varies with how fast the machine you are running the mod on and how often you want animals to be replaced. Therefore I have released 4 different files, each with a different number.
To prevent crashes we use a cooldown of 10 ticks; check if there are any habitats; check if the selected habitat is empty; and check if the selected animal is boxed or pregnant. If the answer to any of these is yes, no animals get replaced.
Lastly we also check if the game is paused. If the game is paused we do not randomize any animals.
All of this results in the following code:
RandomAnimalsManager.Advance = function(self, _nDeltaTime, _nUnscaledDeltaTime)
local worldScript = ((api.world).GetScript)(((api.world).GetActive)())
local scenarioManager = (worldScript.tEnvironment):RequireInterface("Interfaces.IScenarioManager")
local sGameMode = scenarioManager and scenarioManager:GetGameMode() or nil
if sGameMode == "Sandbox" and cooldown >= 10 and math.random(1, 7500) == 1 then
local worldScript = ((api.world).GetScript)("sandbox")
local mainHUD = worldScript:GetHUD()
local tSimTimeData = (mainHUD):GetSimulationTimeSettings()
local bIsPaused = tSimTimeData.bPaused
if not bIsPaused then
local tHabitats = habitatAPI:GetHabitats()
local numberOfHabitats = #tHabitats
if numberOfHabitats > 0 then
local nHabitatEntityID = tHabitats[math.random(1,numberOfHabitats)]
local tAnimals = habitatAPI:GetAnimalsInHabitat(nHabitatEntityID)
local numberOfAnimalsInHabitat = #tAnimals
if numberOfAnimalsInHabitat > 0 then
local nAnimalID = tAnimals[math.random(1, numberOfAnimalsInHabitat)]
local isBoxed = animalsAPI:IsAnimalBoxed(nAnimalID)
local isPregnant = animalsAPI:IsPregnant(nAnimalID)
if not isBoxed and not isPregnant then
local animalGUID = animalsAPI:EntityIDToAnimalGUID(nAnimalID)
local ageStatus = animalsAPI:GetAgeStatus(nAnimalID)
local age = 1
if ageStatus == animalsAPI.Juvenile then
age = 0
end
local sName = animalsAPI:GetName(nAnimalID)
local resultsTable = facilitiesAPI:CreateAnimalInHabitat(nHabitatEntityID, animalsAPI:GetGender(nAnimalID), age, self.tAnimalsToSpawn[math.random(1, self.iNumberOfAnimals)])
animalsAPI:RehomeAnimal(nAnimalID)
cooldown = 0
end
end
end
end
end
cooldown = cooldown + 1
end