Jupiters Posted September 6, 2015 Share Posted September 6, 2015 Hello @DarkXero,Thanks for your generous help this summer. I have learnt a lot from you. You're just like my mentor of modding. I can't thank you enough!Since I have asked you so many questions, would you mind if I ask you one more question?I have been thinking about the world regrowth for DST these days. How to make the world renewable. There is a mod "renewable world" do a good job. But it has some shortages. For example, the beefalo can reproduce themselves. With this mod, if a beefalo is killed, the world will spawn a new beefalo, which makes the world flood with beefalos.I think the mod base on the current amount of a specific prefab. Once it is removed, another will spawn in the world.I want to make a mod base on the mod, which you make for me before, Respawnable Rocks.I want set a limited amount of a specific prefab once the game launchs. The limited amount is the amount of the prefab when game launchs. The component will check the current amount of the prefab periodically and if the current amonut < the limited amount, the world will spawn the prefab.Is that possible? Can you make a sample for me, such as beefalo and berrybush regrowth. Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/ Share on other sites More sharing options...
DarkXero Posted September 7, 2015 Share Posted September 7, 2015 @Jupiters:local c_countprefabs = GLOBAL.c_countprefabslocal GROUND = GLOBAL.GROUNDlocal SpawnPrefab = GLOBAL.SpawnPrefablocal Vector3 = GLOBAL.Vector3local function TrySpawnBeefalo() local pt = 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 ~= GROUND.IMPASSABLE and tile ~= GROUND.INVALID and tile ~= 255 canspawn = canspawn and (tile == GROUND.SAVANNA) if canspawn then local b = SpawnPrefab("beefalo") b.Transform:SetPosition(pt:Get()) else TrySpawnBeefalo() endendlocal function TrySpawnBerry() local pt = 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 ~= GROUND.IMPASSABLE and tile ~= GROUND.INVALID and tile ~= 255 canspawn = canspawn and (tile == GROUND.GRASS or tile == GROUND.FOREST or tile == GROUND.DECIDUOUS) if canspawn then local b = SpawnPrefab("berrybush") b.Transform:SetPosition(pt:Get()) else TrySpawnBerry() endendlocal min_prefabs = { beefalo = { 10, TrySpawnBeefalo }, berrybush = { 40, TrySpawnBerry },}local function updateWorld() for k, v in pairs(min_prefabs) do local numtospawn = v[1] - c_countprefabs(k, true) if numtospawn > 0 then for i = 1, numtospawn, 1 do v[2]() end end endendAddPrefabPostInit("world", function(inst) if inst.ismastersim then inst:ListenForEvent("ms_cyclecomplete", updateWorld) endend) Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-670172 Share on other sites More sharing options...
Jupiters Posted September 7, 2015 Author Share Posted September 7, 2015 local min_prefabs = { beefalo = { 10, TrySpawnBeefalo }, berrybush = { 40, TrySpawnBerry }, } Thank you! This is exactly what I want except that I want the amount of a specific prefab to be based on the amount of the prefab the first time the mod is enabled, not a number that I set it to be. inst:ListenForEvent("ms_cyclecomplete", updateWorld) "ms_cyclecomplete" is a cycle of a day. What the event name of season change and a year cycle? If the mod is done, is it a server only mod or a all clients required mod? Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-670259 Share on other sites More sharing options...
Jupiters Posted September 7, 2015 Author Share Posted September 7, 2015 By the way, there are so many "stack" related mod to make stuff stack to 999 or more but they have a common problem. When stuffs stack more that 256, the amount display goes wrong. Why is that? Is this a technical problem that can't be solved by mods? In DS, stuff can be stacked to 999 with mod enabled. Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-670279 Share on other sites More sharing options...
DarkXero Posted September 7, 2015 Share Posted September 7, 2015 what I want except that I want the amount of a specific prefab to be based on the amount of the prefab the first time the mod is enabled, not a number that I set it to be. You want the world to load. Then the mod to load. Then to count all beefalo in world (e.g 40), then have this number be the minimum? What the event name of season change The event is "seasontick". But that one contains more than just the season.local function onSeasonChange(inst, season) print("Season is now", season)endinst:WatchWorldState("season", onSeasonChange)Is what you want. and a year cycle? No such thing as a year exists.I suppose you can view it aslocal year_length = TUNING.AUTUMN_LENGTH + TUNING.WINTER_LENGTH + TUNING.SPRING_LENGTH + TUNING.SUMMER_LENGTHlocal year = TheWorld.state.cycles % year_length If the mod is done, is it a server only mod or a all clients required mod? Server only. By the way, there are so many "stack" related mod to make stuff stack to 999 or more but they have a common problem. When stuffs stack more that 256, the amount display goes wrong. Why is that? Is this a technical problem that can't be solved by mods? In DS, stuff can be stacked to 999 with mod enabled. This is thanks to stackable_replica screwing with the netvars because the size isn't enough.We have to override its constructor to replace the net variables.GLOBAL.TUNING.STACK_SIZE_LARGEITEM = 999local r_s = GLOBAL.require("components/stackable_replica")r_s._ctor = function(self, inst) self.inst = inst self._stacksize = GLOBAL.net_shortint(inst.GUID, "stackable._stacksize", "stacksizedirty") self._maxsize = GLOBAL.net_tinybyte(inst.GUID, "stackable._maxsize")endNow you can stack 999 boards. If you put this in the mod, it will be client required though. Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-670413 Share on other sites More sharing options...
Jupiters Posted September 8, 2015 Author Share Posted September 8, 2015 You want the world to load. Then the mod to load. Then to count all beefalo in world (e.g 40), then have this number be the minimum? Thanks for reply every question patiently. Yes, that's what I want. Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-670526 Share on other sites More sharing options...
DarkXero Posted September 8, 2015 Share Posted September 8, 2015 @Jupiters, useAddPrefabPostInit("world", function(inst) if inst.ismastersim then inst:AddComponent("minspawner") endend)with thislocal function TrySpawnBeefalo() local pt = 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 ~= GROUND.IMPASSABLE and tile ~= GROUND.INVALID and tile ~= 255 canspawn = canspawn and (tile == GROUND.SAVANNA) if canspawn then local b = SpawnPrefab("beefalo") b.Transform:SetPosition(pt:Get()) else TrySpawnBeefalo() endend local function TrySpawnBerry() local pt = 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 ~= GROUND.IMPASSABLE and tile ~= GROUND.INVALID and tile ~= 255 canspawn = canspawn and (tile == GROUND.GRASS or tile == GROUND.FOREST or tile == GROUND.DECIDUOUS) if canspawn then local b = SpawnPrefab("berrybush") b.Transform:SetPosition(pt:Get()) else TrySpawnBerry() endendlocal MinSpawner = Class(function(self, inst) self.inst = inst self.mins = { beefalo = nil, berrybush = nil, } self.func = { beefalo = TrySpawnBeefalo, berrybush = TrySpawnBerry, } self.needmins = true inst:ListenForEvent("ms_cyclecomplete", function() self:updateWorld() end)end)function MinSpawner:updateWorld() if self.needmins == true then self.mins.beefalo = c_countprefabs("beefalo", true) self.mins.berrybush = c_countprefabs("berrybush", true) self.needmins = false end for k, v in pairs(self.mins) do local numtospawn = self.mins[k] - c_countprefabs(k, true) if numtospawn > 0 then for i = 1, numtospawn, 1 do self.func[k]() end end endendfunction MinSpawner:OnSave() local data = {} for k, v in pairs(self.mins) do data[k] = v end data.needmins = self.needmins return dataendfunction MinSpawner:OnLoad(data) if data then for k, v in pairs(data) do self.mins[k] = v end self.needmins = data.needmins endendreturn MinSpawnerMinimums are needed at the start, then when they are set up, the needmins gets set to false and will load false. Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-670536 Share on other sites More sharing options...
Jupiters Posted September 8, 2015 Author Share Posted September 8, 2015 @DarkXero Thanks for fast reply. Something goes wrong. [00:02:12]: [string "../mods/World Regrowth/scripts/components/m..."]:51: attempt to perform arithmetic on field '?' (a boolean value)LUA ERROR stack traceback: ../mods/World Regrowth/scripts/components/minspawner.lua:51 in (method) updateWorld (Lua) <44-58> ../mods/World Regrowth/scripts/components/minspawner.lua:41 in (local) fn (Lua) <41-41> scripts/entityscript.lua:941 in (method) PushEvent (Lua) <935-958> scripts/components/clock.lua:225 in (method) OnUpdate (Lua) <193-281> scripts/update.lua:183 in () ? (Lua) <146-219>World Regrowth.zip Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-670546 Share on other sites More sharing options...
Jupiters Posted September 8, 2015 Author Share Posted September 8, 2015 @DarkXero I try to make it without component like this. And it works. But the code is too awkward. Would you please help me make it more flexible or do it your way with component? I don't which is the better way make the mod. World Regrowth - 1.zip Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-670552 Share on other sites More sharing options...
DarkXero Posted September 9, 2015 Share Posted September 9, 2015 (edited) @Jupiters,AddPrefabPostInit("world", function(inst) if inst.ismastersim then inst:AddComponent("minspawner") endend)minspawner.lua Edited September 9, 2015 by DarkXero Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-670843 Share on other sites More sharing options...
Jupiters Posted September 9, 2015 Author Share Posted September 9, 2015 @DarkXero WOW, how amazing! You are just like a magician. Thank you!!! I know c_countprefabs() is used for count the number of the prefab existing the world, no matter whether it's in the container or in the players' inventory. How to count the prefab that is not in the container or inventory? For instance, the flint. I want to count the flints that is on the ground. Is is possible? Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-670877 Share on other sites More sharing options...
DarkXero Posted September 9, 2015 Share Posted September 9, 2015 @Jupiters, use a function like:function c_countprefabsonground(prefab, noprint) local count = 0 for k, v in pairs(Ents) do local owner = v.components.inventoryitem and v.components.inventoryitem.owner if owner == nil then if v.prefab == prefab then count = count + 1 end end end if not noprint then print("There are ", count, prefab.."s in the world's ground.") end return countend Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-670882 Share on other sites More sharing options...
Jupiters Posted September 9, 2015 Author Share Posted September 9, 2015 @DarkXero SO COOL! Thank you. Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-670957 Share on other sites More sharing options...
Jupiters Posted September 10, 2015 Author Share Posted September 10, 2015 Hello, @DarkXero, if I want to make this mod compatible with DS, how can I check the place? That's to say, what code can check that the player is on ground, cave or ruins. Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-671269 Share on other sites More sharing options...
Jupiters Posted September 10, 2015 Author Share Posted September 10, 2015 By the way, is there a console command that can print the tile type under cursor? Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-671270 Share on other sites More sharing options...
DarkXero Posted September 11, 2015 Share Posted September 11, 2015 check that the player is on ground, cave or ruins. GetWorld().IsCave()GetWorld().IsRuins() a console command that can print the tile type under cursor? -- Print the (visual) tile under the cursorfunction c_tile() local s = "" local ground = GetWorld() local mx, my, mz = TheInput:GetWorldPosition():Get() local tx, ty = ground.Map:GetTileCoordsAtPoint(mx,my,mz) s = s..string.format("world[%f,%f,%f] tile[%d,%d] ", mx,my,mz, tx,ty) local tile = ground.Map:GetTileAtPoint(TheInput:GetWorldPosition():Get()) for k,v in pairs(GROUND) do if v == tile then s = s..string.format("ground[%s] ", k) break end end print(s)end Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-671481 Share on other sites More sharing options...
Jupiters Posted September 11, 2015 Author Share Posted September 11, 2015 @DarkXero Thank you very much~ So I should write this in modmain.lua: AddPrefabPostInit("forest", function(inst) inst:AddComponent("minspawner_forest") end) AddPrefabPostInit("cave", function(inst) inst:AddComponent("minspawner_cave") end) And in the component mindpawner_cave, I use GetWorld().IsCave() and GetWorld().IsRuins() to check whether the player is on cave or ruins. Am I right? Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-671500 Share on other sites More sharing options...
DarkXero Posted September 11, 2015 Share Posted September 11, 2015 @Jupiters, forest is the overworld's prefab.cave is the caves and the ruins prefab. So yes. Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-671502 Share on other sites More sharing options...
Jupiters Posted September 11, 2015 Author Share Posted September 11, 2015 @Jupiters, forest is the overworld's prefab.cave is the caves and the ruins prefab. So yes. Okay, Thank you. I will try this. Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-671503 Share on other sites More sharing options...
Jupiters Posted September 11, 2015 Author Share Posted September 11, 2015 @DarkXero Is the event still "ms_cyclecomplete" in DS? Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-671504 Share on other sites More sharing options...
DarkXero Posted September 11, 2015 Share Posted September 11, 2015 @Jupiters, no, it's "daycomplete". Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-671547 Share on other sites More sharing options...
Jupiters Posted September 11, 2015 Author Share Posted September 11, 2015 (edited) @Jupiters, no, it's "daycomplete". Thanks, get it. I have an annoying on my dedicated server: beefalo biome always flood with beefalos. How to stop their reproduction where the number of beefalo is up to 30 or 40 or other numbers? Edited September 11, 2015 by Jupiters Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-671599 Share on other sites More sharing options...
DarkXero Posted September 12, 2015 Share Posted September 12, 2015 @Jupiters, hmmm, countprefabs would be expensive for this particular task. This should be less expensive:local worldbeefalonum = 0local function prefabEditsNum(inst) if not GLOBAL.TheWorld.ismastersim then return end worldbeefalonum = worldbeefalonum + 1 inst:ListenForEvent("onremove", function() worldbeefalonum = worldbeefalonum - 1 end)endAddPrefabPostInit("beefalo", prefabEditsNum)AddPrefabPostInit("babybeefalo", prefabEditsNum)AddPrefabPostInit("beefaloherd", function(inst) if not GLOBAL.TheWorld.ismastersim then return end local _spawntest = inst.components.periodicspawner.spawntest local function mytest(inst) if worldbeefalonum > GLOBAL.TheWorld.components.minspawner.minprefs.beefalo then return false end return _spawntest(inst) end inst.components.periodicspawner:SetSpawnTestFn(mytest)end)Used with the minspawner component to take advantage of the minimum. Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-671743 Share on other sites More sharing options...
Jupiters Posted September 12, 2015 Author Share Posted September 12, 2015 @Jupiters, hmmm, countprefabs would be expensive for this particular task.This should be less expensive:local worldbeefalonum = 0local function prefabEditsNum(inst) if not GLOBAL.TheWorld.ismastersim then return end worldbeefalonum = worldbeefalonum + 1 inst:ListenForEvent("onremove", function() worldbeefalonum = worldbeefalonum - 1 end)endAddPrefabPostInit("beefalo", prefabEditsNum)AddPrefabPostInit("babybeefalo", prefabEditsNum)AddPrefabPostInit("beefaloherd", function(inst) if not GLOBAL.TheWorld.ismastersim then return end local _spawntest = inst.components.periodicspawner.spawntest local function mytest(inst) if worldbeefalonum > GLOBAL.TheWorld.components.minspawner.minprefs.beefalo then return false end return _spawntest(inst) end inst.components.periodicspawner:SetSpawnTestFn(mytest)end)Used with the minspawner component to take advantage of the minimum.Thank you!So if the initial number of beefalo is 10 and there are 10 beefalos or more in the world now, the beefalo will not reproduce. And if there are 9 beefalos or less, the beefalo will reproduce themselves? Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-671775 Share on other sites More sharing options...
DarkXero Posted September 12, 2015 Share Posted September 12, 2015 So if the initial number of beefalo is 10 and there are 10 beefalos or more in the world now, the beefalo will not reproduce. And if there are 9 beefalos or less, the beefalo will reproduce themselves? Correct, any beefalo herd prefab will have the spawn test return false if the beefalo world number is higher than the minimum from the minspawner component. prefabEditsNum makes beefalo and babybeefalo edit the counter up when they initialize, and down when they get removed. Link to comment https://forums.kleientertainment.com/forums/topic/57673-world-regrowth-modding/#findComment-671970 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