Kilarin wrote:*snip*
But, now for the serious question. I would like to make ore generation vary according to your location on the map. By height is obvious, since I can set height min and max and can just register the ore with different scarcity numbers at different heights. BUT, I would like to make ore scarcity vary depending on X and Z coords. For example, I might like to make iron ore more likely to generate the further you get from spawn. The math for this would not be at all difficult, I might use
clust_scarcity = 11 * 11 * 11*(1/(abs(x)+abs(z)+1)) (not necessarily a good formula, but gets the idea across)
But this would depend on two factors:
1: Is the value of clust_scarity calculated once at runtime and never again, in which case this approach wouldn't work at all.
2: IF this approach is valid at all, how would I specify the values of the x and z coords?
Thank you very much for any help in correcting my vast oceans of ignorance about minetest mapgen. :)
HeroOfTheWinds wrote:Sadly, register_ores is calculated only once,
HeroOfTheWinds wrote:Sorry if my explanation isn't perfectly clear, I can provide an example if you like
HeroOfTheWinds wrote:Lua Voxel Manipulator (register_on_generated()), and search through every spawned node. Since the LVM is called after the regular mapgen finishes, the ores will already be generated, and all you would need to do is probably call math.random() with a parameter derived from your distance from center. If the random falls in a certain threshold, delete the ore node in question. Just do that for every ore. .
So, and function set up through register_on_generated runs after each and every node in the world is generated. I would then do my register_ore to set the maximum density I wished. I would need to write my on_generated function so that it checked to see if the current node was an ore that I wanted to vary according to distance from spawn, and if it was, possibly remove it (turn into normal stone) based on a random function, thereby creating increasing scarcity as nodes get closer to spawn. Am I following correctly?
I assume that letting minetest generate the ore and lua remove it would be more efficient then trying to write my own ore generation logic in lua? More efficent and MUCH easier.
What kind of impact would this have on map generation speed, probably not a whole lot?
Oh, and one more question. could the deprecated default.generate_ore do what I want? I suppose it would be a very bad idea to use it in any case. :)
and yes, an example (simple!) would be appreciated. I learn best by looking at examples.
minetest.register_on_generated(function(minp, maxp, seed)
--if out of range of ore_gen limits
if minp.y > 0 then
return --quit; otherwise, you'd have wasted resources
end
--easy reference to commonly used values
local t1 = os.clock()
local x1 = maxp.x
local y1 = maxp.y
local z1 = maxp.z
local x0 = minp.x
local y0 = minp.y
local z0 = minp.z
print ("[ore_gen] chunk minp ("..x0.." "..y0.." "..z0..")") --tell people you are generating a chunk
--This actually initializes the LVM
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
local data = vm:get_data()
--grab content IDs -- You need these to efficiently access and set node data. get_node() works, but is far slower
local c_air = minetest.get_content_id("air")
local c_stone = minetest.get_content_id("default:stone")
local c_water = minetest.get_content_id("default:water_source")
local c_lava = minetest.get_content_id("default:lava_source")
local c_iron = minetest.get_content_id("default:stone_with_iron")
local c_diamond = minetest.get_content_id("default:stone_with_diamond")
for z = z0, z1 do -- for each xy plane progressing northwards
for y = y0, y1 do -- for each x row progressing upwards
local vi = area:index(x0, y, z) -- This accesses the node at a given position
for x = x0, x1 do -- for each node do
-- Now test the node if it's an ore that needs to be potentially thinned out
if data[vi] == c_iron or data[vi] == c_diamond then
-- it is, so now thin it based on distance from center
local dist = abs(x) + abs(y) + abs(z) + 1 -- This also accounts for vertical distance, so that you don't need new functions for deeper depths
-- Now threshold it and delete unwanted nodes
if math.random() > (1/dist) then -- 1/dist becomes exceeding small as dist increases. random is between 0 and 1.
data[vi] = c_stone -- remove the ore
end
end -- end ore existence check
end -- end 'x' loop
end -- end 'y' loop
end -- end 'z' loop
-- Wrap things up and write back to map
--send data back to voxelmanip
vm:set_data(data)
--calc lighting
vm:set_lighting({day=0, night=0})
vm:calc_lighting()
--write it to world
vm:write_to_map(data)
local chugent = math.ceil((os.clock() - t1) * 1000) --grab how long it took
print ("[ore_gen] "..chugent.." ms") --tell people how long
end) minetest.register_on_generated(function(minp, maxp, seed)
--if out of range of ore_gen limits
if minp.y > 0 then
return --quit; otherwise, you'd have wasted resources
end
--easy reference to commonly used values
local t1 = os.clock()
local x1 = maxp.x
local y1 = maxp.y
local z1 = maxp.z
local x0 = minp.x
local y0 = minp.y
local z0 = minp.z
print ("[ore_gen] chunk minp ("..x0.." "..y0.." "..z0..")") --tell people you are generating a chunk
--This actually initializes the LVM
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
local data = vm:get_data()
--grab content IDs -- You need these to efficiently access and set node data. get_node() works, but is far slower
local c_air = minetest.get_content_id("air")
local c_stone = minetest.get_content_id("default:stone")
local c_water = minetest.get_content_id("default:water_source")
local c_lava = minetest.get_content_id("default:lava_source")
local c_iron = minetest.get_content_id("default:stone_with_iron")
local c_coal = minetest.get_content_id("default:stone_with_coal")
local c_copper = minetest.get_content_id("default:stone_with_copper")
local c_mese = minetest.get_content_id("default:stone_with_mese")
local c_diamond = minetest.get_content_id("default:stone_with_diamond")
local c_goldblock = minetest.get_content_id("default:goldblock")
for z = z0, z1 do -- for each xy plane progressing northwards
for y = y0, y1 do -- for each x row progressing upwards
local vi = area:index(x0, y, z) -- This accesses the node at a given position
for x = x0, x1 do -- for each node do
-- Now test the node if it's an ore that needs to be potentially thinned out
if data[vi] == c_iron or data[vi] == c_copper or data[vi] == c_mese or data[vi] == c_diamond then
-- it is, so now thin it based on distance from center
local dist = math.abs(x) + math.abs(y) + math.abs(z) + 1 -- This also accounts for vertical distance, so that you don't need new functions for deeper depths
-- Now threshold it and delete unwanted nodes
--if math.random() > (1/dist) then -- 1/dist becomes exceeding small as dist increases. random is between 0 and 1.
if 1 == 1 then -- remove all for test just to prove it is removing the ore
print("[ore_gen] removing ore old="..dump(data[vi]))
--data[vi] = c_stone -- remove the ore
data[vi] = c_goldblock
print(" new="..dump(data[vi]))
end
end -- end ore existence check
end -- end 'x' loop
end -- end 'y' loop
end -- end 'z' loop
-- Wrap things up and write back to map
--send data back to voxelmanip
vm:set_data(data)
--calc lighting
vm:set_lighting({day=0, night=0})
vm:calc_lighting()
--write it to world
vm:write_to_map(data)
local chugent = math.ceil((os.clock() - t1) * 1000) --grab how long it took
print ("[ore_gen] "..chugent.." ms") --tell people how long
end)
end[ore_gen] chunk minp (-32 -112 -192)
[ore_gen] removing ore old=38
new=46
[ore_gen] removing ore old=38
new=46
[ore_gen] removing ore old=38
new=46
... lots and lots more of the same kind of thing :)
[ore_gen] removing ore old=40
new=46
[ore_gen] removing ore old=38
new=46
[ore_gen] removing ore old=38
new=46
[ore_gen] 220 ms
local vi = area:index(x0, y, z) -- This accesses the node at a given position local vi = area:index(x, y, z) -- This accesses the node at a given position --local vi = area:index(x0, y, z) -- This accesses the node at a given position
for x = x0, x1 do -- for each node do
local vi = area:index(x, y, z) -- This accesses the node at a given positionKilarin wrote:Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
--local vi = area:index(x0, y, z) -- This accesses the node at a given position
for x = x0, x1 do -- for each node do
local vi = area:index(x, y, z) -- This accesses the node at a given position
Now works!!! thank you Hero and TeTpaAka!
local vi = area:index(x0, y, z) -- This accesses the node at a given position
for x = x0, x1 do -- for each node do
-- Codes..
vi = vi + 1
endKrock wrote:It's supposed to be used as an array.
HeroOfTheWinds wrote:It doesn't return an element, per se, but rather the index of an element.
drkwv wrote:Maybe a stupid question but why don't minetest have a reaction on a key press? Instead, one should check for get_player_controls() every X ms. Why? Server even could tell a client what combinations it interested in to have a reaction on a custom combinations.
lag01 wrote:But people may click buttons tens of times per second, so bad idea to respond to all that clicks...
register_on_key_press( function(player, keyname, times_pressed), check_delay_ms )12Me21 wrote:does anyone know of a tutorial for making tools in mods? I've seen some before but now I can't find them anymore!
Don wrote:12Me21 wrote:does anyone know of a tutorial for making tools in mods? I've seen some before but now I can't find them anymore!
Check this
viewtopic.php?f=14&t=10729
RHR wrote:Is it possible to override "minetest.register_ore" with a mod? I want to change the height_min and height_max of the minerals in minetest_game default without changing the original mod.
TenPlus1 wrote:Minetest 0.4.11 added 3 new commands to the mix which can clear previous biomes, decoration and ores from a world and let you set your own...
minetest.clear_registered_biomes()
minetest.clear_registered_decorations()
minetest.clear_registered_ores()
TenPlus1 wrote:Minetest 0.4.11 added 3 new commands to the mix which can clear previous biomes, decoration and ores from a world and let you set your own...
minetest.clear_registered_biomes()
minetest.clear_registered_decorations()
minetest.clear_registered_ores()
Hybrid Dog wrote:… but doesn't let you specifically change the default ores.
TeTpaAka wrote:Hybrid Dog wrote:… but doesn't let you specifically change the default ores.
But you could copy the list of registered ores, clear the ores and then reregister the modified ores. It is a little complicated, but it could work.
Napiophelios wrote:I am modifying my creative inventory's formspec and was curious if there was any way
to have the character.png preview image change when I select a different skin?
Hybrid Dog wrote:Fox wrote:Hybrid Dog wrote:l tried to find "legacy_mineral" (with grep -rl) in other files but it's only in ./games/minimal/mods/default/init.lua and ./games/minetest_game/mods/default/nodes.lua. Maybe it's used for decoration.
Hello Hybrd Dog,
Yes, I couldn't find it anywhere else either. Not a mention in lua_api.txt. I didn't know if it was maybe an outdated property, something like decoration as you said, or what. I don't seem to see it in the other mods I have either, so maybe it's something I can ignore like everyone else seems to be doing. xD That it doesn't do anything special I might want, maybe even just does nothing.
Just can't help but wonder though.
found it: viewtopic.php?p=46658#p46658
l need to remove it from my mod…
Fox wrote:Hello all,
Topic: Understanding some bits of tool capabilities?
Reason: I'd just like to understand some parts so I can know what's going on when I make my own tools.
More Info: Let's take the default stone pickaxe.Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
minetest.register_tool("default:pick_stone", {
description = "Stone Pickaxe",
inventory_image = "default_tool_stonepick.png",
tool_capabilities = {
full_punch_interval = 1.3,
max_drop_level=0,
groupcaps={
cracky = {times={[2]=2.0, [3]=1.20}, uses=20, maxlevel=1},
},
damage_groups = {fleshy=3},
},
})
I understand that groupcaps handles what blocks can actually be affected by the tool and how so. I get that uses is tied to the damage inflicted on the tool with use. It's the times and maxlevel part I'm not sure I grasp.
I think the number with fleshy might work similarly?
If someone could help clear up these things, it'd be much appreciated. :)
Users browsing this forum: No registered users and 3 guests