Lumina Posted January 14, 2017 Share Posted January 14, 2017 I have a new plant in one of my mod, working a little like flowers when picked (nothing left on ground). So i want this prefab to spawn to avoid it disappears over time. Ideally i would like it to appears at the start of each autumn. If possible, i would like to have more prefab spawning if there is few prefab, and less if they are a lot, with a limit (like, no spawn if already 50 prefab). Someone could help me to know how to do this ? Component, and after ? Thanks. Link to comment Share on other sites More sharing options...
UnderwearApp Posted January 15, 2017 Share Posted January 15, 2017 Have a look at my grasshoppers mod in the second link of my signature. I do all of this in there except for set a limit but that should be simple enough. I haven't looked through the code in a while but let me know if you have any questions. Link to comment Share on other sites More sharing options...
Lumina Posted January 15, 2017 Author Share Posted January 15, 2017 Thanks, i'll do that and i'll ask questions here if needed Link to comment Share on other sites More sharing options...
Lumina Posted January 17, 2017 Author Share Posted January 17, 2017 @ProfFarnsworth Ok i tried to use your code, modified because if i understand well, you are spawning the grasshoper near grass, and i need to spawn my prefab in a specific ground. But with the change i made, it's not working. HotbushSpawner = Class(function(self, inst) self.inst = inst self.has_spawned = false self.only_spawn_offscreen = true --self.inst:WatchWorldState("iswinter", OnSeasonChange) --self.inst:WatchWorldState("issummer", OnSeasonChange) --self.inst:ListenForEvent("ms_setseason", OnSeasonChange, TheWorld) --self.inst:ListenForEvent("seasonChange", OnSeasonChange) inst:WatchWorldState("season", OnSeasonChange) end) function OnSeasonChange(inst, season) --print("OnSeasonChange entered") --print("The season is currently"..season) inst.components.plant_spawner:OnSeasonChange(inst, season) end function HotbushSpawner:SpawnHotbush(season) --print("Spawning grasshopper") --local season = data.season --if season ~= SEASONS.winter then if TheWorld.state.issummer then for i=1, math.random(6, 12) do if not self.has_spawned then local pt = GLOBAL.Vector3(math.random(-1000, 1000), 0, math.random(-1000, 1000)) local tile = GLOBAL.TheWorld.Map:GetTileAtPoint(pt.x, pt.y, pt.z) local canspawn = tile ~= GLOBAL.GROUND.IMPASSABLE and tile ~= GLOBAL.GROUND.INVALID and tile ~= 255 canspawn = canspawn and (tile == GLOBAL.GROUND.FUNGUSRED) if canspawn then local cave_hot_bush = GLOBAL.SpawnPrefab("cave_hot_bush") cave_hot_bush.Transform:SetPosition(pt:Get()) --print("grasshopper spawned") end end end end self.has_spawned = true end -- function HotbushSpawner:FindSpawnLocation() -- print("Finding spawn location for Grasshopper...") -- local allvalidgrass = {} -- for guid, ent in pairs(Ents) do -- if ent.entity:IsValid() and ent.prefab == "grass" and (not self.only_spawn_offscreen or ent:IsAsleep()) then -- table.insert(allvalidgrass, ent) -- end -- end -- --print("Found "..(# allvalidgrass).." valid grass entities to spawn from") -- if next(allvalidgrass) == nil then -- return -- else -- local spawngrass = GetRandomItem(allvalidgrass) -- return Vector3(spawngrass.Transform:GetWorldPosition()) -- end -- end function HotbushSpawner:OnSeasonChange(inst, season) print("Season change detected") --local season = data.season --if season == SEASONS.winter then end function HotbushSpawner:OnSave() if self.has_spawned then return{has_spawned = self.has_spawned} end end function HotbushSpawner:OnLoad(data) if data then self.has_spawned = data.has_spawned end self:SpawnHotbush() end return HotbushSpawner Do you have any clues about what is wrong with my code ? I used some code found on this forum for the "spawn on ground" part but i don't know if i put it well. Thanks for any help you could give. Link to comment Share on other sites More sharing options...
Aquaterion Posted January 18, 2017 Share Posted January 18, 2017 not sure what this line is meant to be doing: inst.components.plant_spawner:OnSeasonChange(inst, season) but maybe try replacing it with: --this self:SpawnHotbush(season) --or if it gives an error with 'self' then try TheWorld.components.hotbushspawner:SpawnHotbush(season) Link to comment Share on other sites More sharing options...
Lumina Posted January 18, 2017 Author Share Posted January 18, 2017 inst.components.grasshopperspawner:OnSeasonChange(inst, season) The original line in the file was this one, the only one in lower case, so i was wondering it was the name of the file. (my file is plant_spawner for the moment). I'll try your lines as soon as possible to see if it's better, thank. Link to comment Share on other sites More sharing options...
Lumina Posted January 18, 2017 Author Share Posted January 18, 2017 (edited) So i changed the code as suggested (and renamed the file so it's more clear). It's still not working, but i guess it's better because i got an error with the GLOBAL variable, meaning that the code use a part it wasn't using before. Updated code. Spoiler HotbushSpawner = Class(function(self, inst) self.inst = inst self.has_spawned = false self.only_spawn_offscreen = true --self.inst:WatchWorldState("iswinter", OnSeasonChange) --self.inst:WatchWorldState("issummer", OnSeasonChange) --self.inst:ListenForEvent("ms_setseason", OnSeasonChange, TheWorld) --self.inst:ListenForEvent("seasonChange", OnSeasonChange) inst:WatchWorldState("season", OnSeasonChange) end) function OnSeasonChange(inst, season) --print("OnSeasonChange entered") --print("The season is currently"..season) -- inst.components.plant_spawner:OnSeasonChange(inst, season) TheWorld.components.hotbushspawner:SpawnHotbush(season) end function HotbushSpawner:SpawnHotbush(season) --print("Spawning grasshopper") --local season = data.season --if season ~= SEASONS.winter then if TheWorld.state.issummer then for i=1, math.random(6, 12) do if not self.has_spawned then local pt = Vector3(math.random(-1000, 1000), 0, math.random(-1000, 1000)) local tile = TheWorld.Map:GetTileAtPoint(pt.x, pt.y, pt.z) local canspawn = tile ~= GROUND.IMPASSABLE and tile ~= GROUND.INVALID and tile ~= 255 canspawn = canspawn and (tile == GROUND.SAVANNA) if canspawn then local cave_hot_bush = SpawnPrefab("cave_hot_bush") cave_hot_bush.Transform:SetPosition(pt:Get()) --print("grasshopper spawned") end end end end self.has_spawned = true end -- function HotbushSpawner:FindSpawnLocation() -- print("Finding spawn location for Grasshopper...") -- local allvalidgrass = {} -- for guid, ent in pairs(Ents) do -- if ent.entity:IsValid() and ent.prefab == "grass" and (not self.only_spawn_offscreen or ent:IsAsleep()) then -- table.insert(allvalidgrass, ent) -- end -- end -- --print("Found "..(# allvalidgrass).." valid grass entities to spawn from") -- if next(allvalidgrass) == nil then -- return -- else -- local spawngrass = GetRandomItem(allvalidgrass) -- return Vector3(spawngrass.Transform:GetWorldPosition()) -- end -- end function HotbushSpawner:OnSeasonChange(inst, season) print("Season change detected") --local season = data.season --if season == SEASONS.winter then end function HotbushSpawner:OnSave() if self.has_spawned then return{has_spawned = self.has_spawned} end end function HotbushSpawner:OnLoad(data) if data then self.has_spawned = data.has_spawned end self:SpawnHotbush() end return HotbushSpawner So i guess it's this part that doesn't work : function HotbushSpawner:SpawnHotbush(season) --print("Spawning grasshopper") --local season = data.season --if season ~= SEASONS.winter then if TheWorld.state.issummer then for i=1, math.random(6, 12) do if not self.has_spawned then local pt = Vector3(math.random(-1000, 1000), 0, math.random(-1000, 1000)) local tile = TheWorld.Map:GetTileAtPoint(pt.x, pt.y, pt.z) local canspawn = tile ~= GROUND.IMPASSABLE and tile ~= GROUND.INVALID and tile ~= 255 canspawn = canspawn and (tile == GROUND.SAVANNA) if canspawn then local cave_hot_bush = SpawnPrefab("cave_hot_bush") cave_hot_bush.Transform:SetPosition(pt:Get()) --print("grasshopper spawned") end end end end self.has_spawned = true end (I changed ground to savanna for the test, i wanted to be sure it's not the problem.) Edited January 18, 2017 by Lumina Link to comment Share on other sites More sharing options...
UnderwearApp Posted January 18, 2017 Share Posted January 18, 2017 @Lumina What is going wrong? Are you getting an error or is it just not spawning? Link to comment Share on other sites More sharing options...
Lumina Posted January 18, 2017 Author Share Posted January 18, 2017 No error in the log, no crash, just no spawn at all. Link to comment Share on other sites More sharing options...
Aquaterion Posted January 18, 2017 Share Posted January 18, 2017 try this maybe HotbushSpawner = Class(function(self, inst) self.inst = inst self.has_spawned = false --self.only_spawn_offscreen = true --self.inst:WatchWorldState("iswinter", OnSeasonChange) --self.inst:WatchWorldState("issummer", OnSeasonChange) --self.inst:ListenForEvent("ms_setseason", OnSeasonChange, TheWorld) --self.inst:ListenForEvent("seasonChange", OnSeasonChange) self.inst:WatchWorldState("season", function(inst, season) self:OnSeasonChange(inst, season) end) end) function HotbushSpawner:OnSeasonChange(inst, season) print("Season changed to: " .. season) if season == "summer" and not self.has_spawned then self:SpawnHotbush(season) end end function HotbushSpawner:SpawnHotbush(season) --print("Spawning Hotbush") for i=1, math.random(6, 12) do local pt = Vector3(math.random(-1000, 1000), 0, math.random(-1000, 1000)) local tile = TheWorld.Map:GetTileAtPoint(pt.x, pt.y, pt.z) if tile == GROUND.SAVANNA then local cave_hot_bush = SpawnPrefab("cave_hot_bush") cave_hot_bush.Transform:SetPosition(pt:Get()) --print("Hotbush spawned") end end self.has_spawned = true end -- function HotbushSpawner:FindSpawnLocation() -- print("Finding spawn location for Grasshopper...") -- local allvalidgrass = {} -- for guid, ent in pairs(Ents) do -- if ent.entity:IsValid() and ent.prefab == "grass" and (not self.only_spawn_offscreen or ent:IsAsleep()) then -- table.insert(allvalidgrass, ent) -- end -- end -- --print("Found "..(# allvalidgrass).." valid grass entities to spawn from") -- if next(allvalidgrass) == nil then -- return -- else -- local spawngrass = GetRandomItem(allvalidgrass) -- return Vector3(spawngrass.Transform:GetWorldPosition()) -- end -- end function HotbushSpawner:OnSave() if self.has_spawned then return{has_spawned = self.has_spawned} end end function HotbushSpawner:OnLoad(data) if data then self.has_spawned = data.has_spawned end self:SpawnHotbush() end return HotbushSpawner Link to comment Share on other sites More sharing options...
Lumina Posted January 18, 2017 Author Share Posted January 18, 2017 (edited) @Aquaterion I tried this and it didn't work. So i changed different things trying to see if something could work. I got some spawns in this condition I replaced : function HotbushSpawner:OnSeasonChange(inst, season) print("Season changed to: " .. season) if season == "summer" and not self.has_spawned then self:SpawnHotbush(season) end end By function HotbushSpawner:OnSeasonChange(inst, season) print("Season changed to: " .. season) if season == "summer" then self:SpawnHotbush(season) end end And then i got one spawn, with the prints : [00:01:09]: Season changed to: summer [00:01:09]: Spawning Hotbush [00:01:09]: Hotbush spawned (I uncommented the print for my test, but never got the "Spawning Hotbush" with the original code (even with the print uncommented i mean)) So i don't understand why the "if season == "summer" and not self.has_spawned then" doesn't work (and i don't understand how it should work...), but since the "not self.has_spawned" should be a test i guess it's important, so removing it could cause trouble ? Also, in my differents tests, i got only one bush spawning. So i suppose this line "for i=1, math.random(6, 12) do " is here to tell "repeat multiple times", so why i have only one bush ? (If i understand well, it should like something like this : Season changed to: summer Spawning Hotbush Hotbush spawned Hotbush spawned Hotbush spawned Hotbush spawned Hotbush spawned Hotbush spawned ?) Thanks a lot for all your help anyway, all of you, i'm really grateful Edited January 18, 2017 by Lumina Link to comment Share on other sites More sharing options...
Aquaterion Posted January 18, 2017 Share Posted January 18, 2017 the for loop should TRY to spawn 6 to 12 bushes, but if it fails to spawn some, such as trying to spawn it anywhere else that isn't savanna, then that still would count as 1 TRY. you could use a while loop like so: function HotbushSpawner:SpawnHotbush(season) --print("Spawning Hotbush") local currentbushes = 0 local maxbushes = math.random(6, 12) while currentbushes <= maxbushes do local pt = Vector3(math.random(-1000, 1000), 0, math.random(-1000, 1000)) local tile = TheWorld.Map:GetTileAtPoint(pt.x, pt.y, pt.z) if tile == GROUND.SAVANNA then local cave_hot_bush = SpawnPrefab("cave_hot_bush") cave_hot_bush.Transform:SetPosition(pt:Get()) --print("Hotbush spawned") currentbushes = currentbushes + 1 end end self.has_spawned = true end Link to comment Share on other sites More sharing options...
Lumina Posted January 18, 2017 Author Share Posted January 18, 2017 Thanks, it seems to work fine What is the risk if i let the "not self.has_spawned" removed of the test function HotbushSpawner:OnSeasonChange(inst, season) print("Season changed to: " .. season) if season == "summer" then self:SpawnHotbush(season) end end ? Do i have a risk to have too much spawn, for example each time the server will start in summer or something ? Or is it fine to let it this way ? Thanks Link to comment Share on other sites More sharing options...
Aquaterion Posted January 18, 2017 Share Posted January 18, 2017 Honestly, if you want bushes to spawn each summer, then u can remove that variable, as well as the save and load functions. Link to comment Share on other sites More sharing options...
Lumina Posted January 18, 2017 Author Share Posted January 18, 2017 Perfect, thanks again Link to comment Share on other sites More sharing options...
UnderwearApp Posted January 19, 2017 Share Posted January 19, 2017 17 hours ago, Lumina said: Perfect, thanks again Glad you got this sorted. Apologies haven't been around much. If memory serves "self.has_spawned" is a local variable so you should be fine without it. And @Aquaterion is right about the limit function. I don't care if some don't spawn as the grasshoppers reproduce so the while function should work for you since you are not killing them off. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now