Jupiters Posted August 17, 2015 Share Posted August 17, 2015 How to pick the ramdom coordinate in both DS and DST? Link to comment Share on other sites More sharing options...
Jupiters Posted August 30, 2015 Author Share Posted August 30, 2015 @DarkXero Since the topic has posted for a long time and no one posted, I come to you for help. I want to spawn rocks when they are mined. But I don't know how to pick a random coordinate on rocky ground in DS and DST, Especially DS. Link to comment Share on other sites More sharing options...
DarkXero Posted August 30, 2015 Share Posted August 30, 2015 @Jupiters,there are many checks that can be done. For example, in shadowmeteor.lua: for i, v in ipairs(inst.loot) do if math.random() <= v.chance then local canspawn = true if v.radius ~= nil then --Check if there's space to deploy rocks --Similar to CanDeployAtPoint check in map.lua local ents = TheSim:FindEntities(x, y, z, v.radius, nil, { "NOBLOCK", "FX" }) for k, v in pairs(ents) do if v ~= inst and not launched[v] and v.entity:IsValid() and v.entity:IsVisible() and v.components.placer == nil and v.entity:GetParent() == nil then canspawn = false break end end end if canspawn then local drop = SpawnPrefab(v.prefab) if drop ~= nil then drop.Transform:SetPosition(x, y, z) if drop.components.inventoryitem ~= nil then drop.components.inventoryitem:OnDropped(true) end end end end endHere you have checks for valid placement. Or in the component, lootdropper.lua: if loot.Physics ~= nil then local angle = math.random() * 2 * PI local speed = math.random() * 2 if loot:IsAsleep() then local radius = .5 * speed + (self.inst ~= nil and self.inst.Physics ~= nil and (loot.Physics:GetRadius() or 1) + (self.inst.Physics:GetRadius() or 1) or 0) loot.Transform:SetPosition( pt.x + math.cos(angle) * radius, 0, pt.z + math.sin(angle) * radius ) SplashOceanLoot(loot) else loot.Physics:SetVel(speed * math.cos(angle), GetRandomWithVariance(8, 4), speed * math.sin(angle)) if self.inst ~= nil and self.inst.Physics ~= nil then local radius = (loot.Physics:GetRadius() or 1) + (self.inst.Physics:GetRadius() or 1) loot.Transform:SetPosition( pt.x + math.cos(angle) * radius, pt.y, pt.z + math.sin(angle) * radius ) end loot:DoTaskInTime(1, SplashOceanLoot) end endHere you have the stuff being tossed and then checked later in SplashOceanLoot to see if it fell to the ocean. You can even use the checks with inst:GetCurrentTileType() to check if the place you want to spawn stuff is GROUND.IMPASSABLE, or use any of the function in components map.lua, like TheWorld.Map:CanPlacePrefabFilteredAtPoint(x, y, z, prefab). However, for what you want to do, this is not necessary.All you have to do is edited the SharedLootTables of the prefabs in rocks.lua.Your typical nitre giving rock is rock1.Your typical gold giving rock is rock2. So what we do is this:-- We run this after the sim started so LootTables got globally declared in any lootdropperAddSimPostInit(function() -- We get the global loot tables created via SetSharedLootTable local _LT = GLOBAL.LootTables -- Now we follow the format inside those tables -- Each element of the table is another table, that consists of a prefab, and the probability to drop -- We add to the shared loot table of rock1, a 1 chance of dropping a blue gem, and 0.5 chance of dropping a red gem table.insert(_LT["rock1"], {"bluegem", 1.00}) table.insert(_LT["rock1"], {"redgem", 0.50}) -- We add to the shared loot table of rock2, a 0.5 chance of dropping a blue gem, and 1 chance of dropping a red gem table.insert(_LT["rock2"], {"bluegem", 0.50}) table.insert(_LT["rock2"], {"redgem", 1.00}) -- In rocks.lua you have the rest of the shared loot tables for the other rocks -- The rock_moon table has moon rock nuggets -- The others just have rocks and more rocksend) Link to comment Share on other sites More sharing options...
Jupiters Posted August 31, 2015 Author Share Posted August 31, 2015 Thank you, @DarkXeroI'm so sorry I didn't make myself clear. What I meant was that the boulder will respawn into the world after it was mined. I try to do it in madmain.lua like this: math.randomseed(GLOBAL.os.time())AddPrefabPostInit("rock1", function( inst ) inst.components.workable:SetOnWorkCallback( function(inst, worker, workleft) local pt = Point(inst.Transform:GetWorldPosition()) if workleft <= 0 then inst.SoundEmitter:PlaySound("dontstarve/wilson/rock_break") inst.components.lootdropper:DropLoot(pt) inst:Remove() local pt = GLOBAL.Vector3(math.random(-1000,1000), 0, math.random(-1000,1000)) GLOBAL.SpawnPrefab("rock1").Transform:SetPosition(pt:Get()) else if workleft < TUNING.ROCKS_MINE*(1/3) then inst.AnimState:PlayAnimation("low") elseif workleft < TUNING.ROCKS_MINE*(2/3) then inst.AnimState:PlayAnimation("med") else inst.AnimState:PlayAnimation("full") end end end)end) The lines in red is what what I added and the line in blue already existed in rocks.lua.As you can see, I want to override inst.components.workable:SetOnWorkCallback() .The lines in red is what I added to pick a random coordinate and spawn a rock1. But it will spawn on the see. How do I filter the coordinate that is ground(the tile is rocky or dirt, etc). Is there a better to excute these function other than override inst.components.workable:SetOnWorkCallback() ? By the way, this is for DS. Link to comment Share on other sites More sharing options...
DarkXero Posted August 31, 2015 Share Posted August 31, 2015 @Jupiters:local function TrySpawn() local pt = GLOBAL.Vector3(math.random(-1000, 1000), 0, math.random(-1000, 1000)) local tile = GLOBAL.GetWorld().Map:GetTileAtPoint(pt.x, pt.y, pt.z) local canspawn = tile ~= GLOBAL.GROUND.IMPASSABLE and tile ~= GLOBAL.GROUND.INVALID if canspawn then print("Rock respawned!") GLOBAL.SpawnPrefab("rock1").Transform:SetPosition(pt:Get()) else print("Position invalid. Trying again...") TrySpawn() endend--math.randomseed(GLOBAL.os.time())AddPrefabPostInit("rock1", function( inst ) local _onwork = inst.components.workable.onwork inst.components.workable.onwork = function(inst, worker, workleft) if workleft <= 0 then TrySpawn() end _onwork(inst, worker, workleft) endend)You can attach your function to onwork, like this. Link to comment Share on other sites More sharing options...
Jupiters Posted August 31, 2015 Author Share Posted August 31, 2015 (edited) @DarkXero You are such a genius!!!!!! Thank you. But with one problem, the boulder will respawn out of the map, on the black zone. I reduce the number 1000 to 650, and it works. But is there any other solution that I dont need to reduce the number of math.random? Because I need it covers all the area of map when the map size is different. Plus, why there is no components map.lua in DS. Edited August 31, 2015 by Jupiters Link to comment Share on other sites More sharing options...
DarkXero Posted August 31, 2015 Share Posted August 31, 2015 @Jupiters:local canspawn = tile ~= GLOBAL.GROUND.IMPASSABLE and tile ~= GLOBAL.GROUND.INVALID and tile ~= 255this way you won't need to reduce the range. Link to comment Share on other sites More sharing options...
Jupiters Posted August 31, 2015 Author Share Posted August 31, 2015 @DarkXero tile ~= 255 What does "255" mean? Link to comment Share on other sites More sharing options...
DarkXero Posted August 31, 2015 Share Posted August 31, 2015 What does "255" mean? Apparently that's the code for the black squares out of bounds. Link to comment Share on other sites More sharing options...
Jupiters Posted August 31, 2015 Author Share Posted August 31, 2015 Apparently that's the code for the black squares out of bounds. Thank you, it works now.I want to use inst:DoTaskInTime() to delay the rock spawn so that the rock will not spawn immediately. But DoTaskInTime will be interrupted when I reload the game. Are there other funtions? Link to comment Share on other sites More sharing options...
DarkXero Posted September 1, 2015 Share Posted September 1, 2015 @Jupiters, here.I made a component.It saves times to spawn, and when it updates, it checks every time in case it's below 0 and then tries to spawn.RockSpawner.zip Link to comment Share on other sites More sharing options...
Jupiters Posted September 1, 2015 Author Share Posted September 1, 2015 @DarkXero I Love You!!!! 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