. . . Posted September 22, 2021 Share Posted September 22, 2021 (edited) hello, I need help I'm really new to this thing I'm trying out and have no idea how to achieve it lol so, i'm trying to spawn in some new stuff into the world and one of the thing i want to spawn is pretty big and needs a good amount of space away from the ocean/water like 15 or 20 radius and i was wondering how would i find such a position? Is there some function or code i can use to find an x,y,z position with a certain distance away from the water/ocean and preferably a way to find random positions in specific biomes? Edited September 27, 2021 by . . . Link to comment https://forums.kleientertainment.com/forums/topic/133855-solved-way-to-find-a-suitable-spot-in-the-world-with-enough-space/ Share on other sites More sharing options...
Monti18 Posted September 22, 2021 Share Posted September 22, 2021 (edited) local offsets = { {6,0}, {6,6}, {-6,6}, {6,-6}, {-6,0}, {0,6}, {0,-6}, {-6,-6}, } local function CheckForWater(pt) for k, v in ipairs(offsets) do local water = TheWorld.Map:IsOceanTileAtPoint(pt.x + v[1],pt.y + v[2],pt.z) if water == true then return false end end local structures = TheSim:FindEntities(pt.x, pt.y, pt.z, 6, {"structure","birdblocker"}) if #structures > 0 then return false end return true end local offset = FindWalkableOffset(pos, math.random() * 360 * math.pi, math.random(400, 800), 500,nil,nil,CheckForWater) This is some code that I used to spawn a chest somewhere but not too close to the ocean and without spawning on top of boulder or something else You use FindWalkableOffset to find an offset from your position that has all the things you need. FindWalkableOffset(position, start_angle, radius, attempts, check_los, ignore_walls, customcheckfn, allow_water, allow_boats) This is the definition of FindWalkableOffset. The important bit for you is the customcheckfn. I think you can use the same as I did with just the offsets made to a higher number. As for the biomes, I think you can add a check like this: local tile = TheWorld.Map:GetTileAtPoint(pt) if tile ~= "whatever_tile_of_the_biome_you_want" then return false end The tiles can be found in constants.lua Edited September 22, 2021 by Monti18 1 Link to comment https://forums.kleientertainment.com/forums/topic/133855-solved-way-to-find-a-suitable-spot-in-the-world-with-enough-space/#findComment-1497310 Share on other sites More sharing options...
. . . Posted September 27, 2021 Author Share Posted September 27, 2021 (edited) @Monti18 Thanks a lot! It seems to work most of the time which's great! The only thing is rarely my thing still spawns too close to the water even with all the offsets being at 30 instead of 6? Do I have to make it a huge number like 100 for that not to happen? And thanks a lot ! ps: it was in a world without caves if that matters Edited September 27, 2021 by . . . Link to comment https://forums.kleientertainment.com/forums/topic/133855-solved-way-to-find-a-suitable-spot-in-the-world-with-enough-space/#findComment-1498695 Share on other sites More sharing options...
Monti18 Posted September 27, 2021 Share Posted September 27, 2021 (edited) You're welcome! I think the problem is that there is too much distance between your starting point and the spawn point, I only added a few offsets so it's won't be as accurate if you get farther. If that's the case, something like this is probably better: local function CheckForWater(pt) local ocean = FindNearbyOcean(pt,30) if ocean then return false end local structures = TheSim:FindEntities(pt.x, pt.y, pt.z, 6, {"structure","birdblocker"}) if #structures > 0 then return false end return true end This is not tested, but I think it should work. If it doesn't, copy the function FindNearbyOcean, change the attempts of the FindValidPositionByFan function to a higher number, somethin like 60 or 180. More attempts means it will check more positions in the radius around the starting point. You can also try to add another check of the ocean at lower distances if there are some problems that still persist. Hope that will make it work now! Edited September 27, 2021 by Monti18 1 Link to comment https://forums.kleientertainment.com/forums/topic/133855-solved-way-to-find-a-suitable-spot-in-the-world-with-enough-space/#findComment-1498723 Share on other sites More sharing options...
. . . Posted September 29, 2021 Author Share Posted September 29, 2021 @Monti18 Hey again! I'm so sorry to bother you again but I must be dumb or something no matter how much I look at your post of increasing the FindValidPositionByFan function FindNearbyOcean(position, range) local finaloffset = FindValidPositionByFan(math.random() * 2 * PI, range or 8, 8, function(offset) local x, z = position.x + offset.x, position.z + offset.z return TheWorld.Map:IsOceanAtPoint(x, 0, z) and not TheWorld.Map:IsPointNearHole(Vector3(x, 0, z)) end) if finaloffset ~= nil then finaloffset.x = finaloffset.x + position.x finaloffset.z = finaloffset.z + position.z return finaloffset end end and think what I have to do I can't figure it out how I would increase it looks so complicated it makes my brain just stop thinking there's a problem that sometimes the thing i want to spawn doesn't even spawn in the world which i guess needs to change the FindValidPositionByFan to make it check more do you know what I would change? sorry to bother This is the current code for finding a place to spawn the thing too local function CheckForThing(pt) local ocean = GLOBAL.FindNearbyOcean(pt, 20) if ocean then return false end local structures = TheSim:FindEntities(pt.x, pt.y, pt.z, 15, {"structure", "birdblocker", "antlion_sinkhole_blocker"}) if #structures > 0 then return false end local ents = TheSim:FindEntities(pt.x, pt.y, pt.z, 15, nil, nil, {"tree", "plant", "renewable", "tentacle"}) for k, v in pairs(ents) do if v ~= nil then v:Remove() end end return true end local function SpawnThing(inst) local pos = inst:GetPosition() local offset = GLOBAL.FindWalkableOffset(pos, math.random() * 360 * math.pi, math.random(400, 800), 500, nil, nil, CheckForThing) if offset then local spawn_pos = pos + offset local a = SpawnPrefab("giantmeteor") a.Transform:SetPosition(spawn_pos:Get()) end end Link to comment https://forums.kleientertainment.com/forums/topic/133855-solved-way-to-find-a-suitable-spot-in-the-world-with-enough-space/#findComment-1499828 Share on other sites More sharing options...
Monti18 Posted September 29, 2021 Share Posted September 29, 2021 (edited) local function IsOceanHere(position, range) local finaloffset = FindValidPositionByFan(math.random() * 2 * PI, range or 8, 60, function(offset) local x, z = position.x + offset.x, position.z + offset.z return TheWorld.Map:IsOceanAtPoint(x, 0, z) and not TheWorld.Map:IsPointNearHole(Vector3(x, 0, z)) end) if finaloffset ~= nil then finaloffset.x = finaloffset.x + position.x finaloffset.z = finaloffset.z + position.z return finaloffset end end The argument behind the range is the attempts argument, this is the one you need to increase. I increased it here to 60. You need to have a very open position for this to work, and if you try it, you will always have the same distance from your starting point. To get more different postitions, I would try this: local function CheckForThing(pt) local ocean = IsOceanHere(pt, 20) if ocean then return false end local structures = TheSim:FindEntities(pt.x, pt.y, pt.z, 15, {"structure", "birdblocker", "antlion_sinkhole_blocker"}) if #structures > 0 then return false end local ents = TheSim:FindEntities(pt.x, pt.y, pt.z, 15, nil, nil, {"tree", "plant", "renewable", "tentacle"}) for k, v in pairs(ents) do if v ~= nil then v:Remove() end end return true end local tries = 0 local MAX_TRIES = 10 local function SpawnThing(inst) local pos = inst:GetPosition() local offset = GLOBAL.FindWalkableOffset(pos, math.random() * 360 * math.pi, math.random(400, 800), 500, nil, nil, CheckForThing) if offset then tries = 0 local spawn_pos = pos + offset local a = SpawnPrefab("giantmeteor") a.Transform:SetPosition(spawn_pos:Get()) else tries = tries + 1 if tries < MAX_TRIES then SpawnThing(inst) end end end This will make it try to spawn your thing 10 times, which will be at different radius as you run math.random each time. You can increase the MAX_TRIES if you need it to run more often. I hope that it will work now Edited September 29, 2021 by Monti18 1 Link to comment https://forums.kleientertainment.com/forums/topic/133855-solved-way-to-find-a-suitable-spot-in-the-world-with-enough-space/#findComment-1499886 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