Post your modding questions here

Locked
User avatar
bobomb
Member
Posts: 162
Joined: Sat May 23, 2015 20:28
GitHub: bobombolo
IRC: bobomb

Re: Post your modding questions here

by bobomb » Post

what is the best method to determine surface height given an x,z coordinate? is there something in the lua api? is there a preferred algorithm?

i found this but it was never merged? https://github.com/minetest/minetest/pull/640

thanks

User avatar
Hybrid Dog
Member
Posts: 2828
Joined: Thu Nov 01, 2012 12:46
GitHub: HybridDog

Re: Post your modding questions here

by Hybrid Dog » Post

bobomb wrote:what is the best method to determine surface height given an x,z coordinate? is there something in the lua api? is there a preferred algorithm?

i found this but it was never merged? https://github.com/minetest/minetest/pull/640

thanks
ln which situation do you need to find out the surface height?
mapgen for example offers a heightmap mapgen_object

‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪

User avatar
bobomb
Member
Posts: 162
Joined: Sat May 23, 2015 20:28
GitHub: bobombolo
IRC: bobomb

Re: Post your modding questions here

by bobomb » Post

i have solved this but the situation is not a mapgen situation. it is after the world is generated.

I ended up converting a function made for core that was never merged from: https://github.com/sapier/minetest/blob ... t.cpp#L868

here it is:

Code: Select all

function get_surface(basepos, searchup, searchdown, walkable_only)

	local max = searchup + basepos.y
	if searchdown then basepos.y = basepos.y - searchdown end
	local last_node = minetest.get_node(basepos)
	local node = last_node
	local runpos = basepos

	local last_was_walkable = node.walkable

	while ( runpos.y < max and minetest.get_content_id(node.name) ~= c_air ) do
		runpos.y = runpos.y + 1
		last_node = node
		node = minetest.get_node(runpos)

		if not (walkable_only) then
			if minetest.get_content_id(last_node.name) ~= c_air
			and minetest.get_content_id(last_node.name) ~= c_ignore
			and minetest.get_content_id(node.name) == c_air then
				return runpos.y
			end
		else
			local is_walkable = node.walkable
			if last_was_walkable and not is_walkable then
				return runpos.y
			end
			last_was_walkable = is_walkable
		end
	end

	return basepos.y - 1
end
there are still some issues with this, like it returns max when nothing no air was detected, and it returns 0 when no ground was detected. also i don't know how to test for "is_walkable" in lua. how does one test a node for various group memberships, and is walkability a group or something else in the lua api?

User avatar
Hybrid Dog
Member
Posts: 2828
Joined: Thu Nov 01, 2012 12:46
GitHub: HybridDog

Re: Post your modding questions here

by Hybrid Dog » Post

bobomb wrote:i have solved this but the situation is not a mapgen situation. it is after the world is generated.

I ended up converting a function made for core that was never merged from: https://github.com/sapier/minetest/blob ... t.cpp#L868

here it is:

Code: Select all

function get_surface(basepos, searchup, searchdown, walkable_only)

	local max = searchup + basepos.y
	if searchdown then basepos.y = basepos.y - searchdown end
	local last_node = minetest.get_node(basepos)
	local node = last_node
	local runpos = basepos

	local last_was_walkable = node.walkable

	while ( runpos.y < max and minetest.get_content_id(node.name) ~= c_air ) do
		runpos.y = runpos.y + 1
		last_node = node
		node = minetest.get_node(runpos)

		if not (walkable_only) then
			if minetest.get_content_id(last_node.name) ~= c_air
			and minetest.get_content_id(last_node.name) ~= c_ignore
			and minetest.get_content_id(node.name) == c_air then
				return runpos.y
			end
		else
			local is_walkable = node.walkable
			if last_was_walkable and not is_walkable then
				return runpos.y
			end
			last_was_walkable = is_walkable
		end
	end

	return basepos.y - 1
end
there are still some issues with this, like it returns max when nothing no air was detected, and it returns 0 when no ground was detected. also i don't know how to test for "is_walkable" in lua. how does one test a node for various group memberships, and is walkability a group or something else in the lua api?
node.walkable is nil because node is from minetest.get_node(pos), which returns a table containing the name, param1 and param2 of the node at pos
this function should test if a node is walkable:

Code: Select all

-- is_walkable(minetest.get_node(pos).name)

local function is_walkable(name)
local data = minetest.registered_nodes[name]
if not data then
return false
end
return not (data.walkable == false)
end
walkable is not a group, it's something of the node definition, groups is something of the node definition, too
if you want to find out if a node is in a specific group, there's a function for it http://dev.minetest.net/minetest.get_item_group

‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪

User avatar
bobomb
Member
Posts: 162
Joined: Sat May 23, 2015 20:28
GitHub: bobombolo
IRC: bobomb

Re: Post your modding questions here

by bobomb » Post

i knew that walkable code would not work, anyway here is a complete translation of sapier's function without any changes like "downsearch" which is redundant. (still need to deal with cases of no top found / no bottom found)

Code: Select all

-- a lua rewrite of sapier's get_surface() proposal, see:
-- https://github.com/sapier/minetest/blob/c6f814b52a5e2b2f12c76215db3524571c56fe20/src/environment.cpp#L868
function get_surface(basepos, searchup, walkable_only)

	local max = searchup + basepos.y
	local last_node = minetest.get_node(basepos)
	local node = last_node
	local runpos = basepos

	local last_was_walkable = minetest.registered_nodes[node.name].walkable

	while ( runpos.y < max and minetest.get_content_id(node.name) ~= c_air ) do
		runpos.y = runpos.y + 1
		last_node = node
		node = minetest.get_node(runpos)

		if not (walkable_only) then
			if minetest.get_content_id(last_node.name) ~= c_air
			and minetest.get_content_id(last_node.name) ~= c_ignore
			and minetest.get_content_id(node.name) == c_air then
				return runpos.y
			end
		else
			local is_walkable = minetest.registered_nodes[node.name].walkable
			if last_was_walkable and not is_walkable then
				return runpos.y
			end
			last_was_walkable = is_walkable
		end
	end

	return basepos.y - 1
end

User avatar
rubenwardy
Moderator
Posts: 6972
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: Bristol, United Kingdom
Contact:

Re: Post your modding questions here

by rubenwardy » Post

Hybrid Dog wrote:

Code: Select all

local data = minetest.registered_nodes[name]if not data then
    return false
end
return not (data.walkable == false)
Would be simpler as:

Code: Select all

return data and data.walkable
Table look ups can be costly. minetest.get_node can also be costly. get_node will return { name = "ignore" } is the MapBlock hasn't been loaded yet. Node that there may be stacked worlds - floating lands etc at 30000 (in the future) and you may be in a cave.
Renewed Tab (my browser add-on) | Donate | Mods | Minetest Modding Book

Hello profile reader

User avatar
bobomb
Member
Posts: 162
Joined: Sat May 23, 2015 20:28
GitHub: bobombolo
IRC: bobomb

Re: Post your modding questions here

by bobomb » Post

Thanks Ruben. I am going to revise the function to handle caves and skylands, one way or another. My first approach was to make it relative to the player, but anyway that is on the to do list...

is Hybrid Dog's function necessary or can I just do

Code: Select all

return minetest.registered_nodes[node.name].walkable
i know node name exists because that's what's being tested.

User avatar
rubenwardy
Moderator
Posts: 6972
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: Bristol, United Kingdom
Contact:

Re: Post your modding questions here

by rubenwardy » Post

There may be unknown nodes in the world, this will cause the game to crash.
Renewed Tab (my browser add-on) | Donate | Mods | Minetest Modding Book

Hello profile reader

User avatar
Hybrid Dog
Member
Posts: 2828
Joined: Thu Nov 01, 2012 12:46
GitHub: HybridDog

Re: Post your modding questions here

by Hybrid Dog » Post

rubenwardy wrote:
Hybrid Dog wrote:

Code: Select all

local data = minetest.registered_nodes[name]if not data then
    return false
end
return not (data.walkable == false)
[/quote

Would be simpler as:

Code: Select all

return data and data.walkable
l'm not sure if this works.
But you could short it this way:

Code: Select all

local data = minetest.registered_nodes[name]
return data and data.walkable ~= false

‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪

User avatar
bobomb
Member
Posts: 162
Joined: Sat May 23, 2015 20:28
GitHub: bobombolo
IRC: bobomb

Re: Post your modding questions here

by bobomb » Post

I rewrote the function to scan from the top down which is much simpler and deals with caves and overhangs at least in a basic way:
https://gist.github.com/bobombolo/6127b153228344eb037a

User avatar
SAMIAMNOT
Member
Posts: 416
Joined: Wed Sep 03, 2014 00:51
In-game: notanewbie
Location: Desert

Re: Post your modding questions here

by SAMIAMNOT » Post

How do you spawn nodes and/or mobs? I tried modding the More Mesecons mod and changed the add_item function to add_node but that did not work for the Mobs Redo mob NPCs.
I test mines.

User avatar
Nathan.S
Member
Posts: 1147
Joined: Wed Sep 24, 2014 17:47
GitHub: NathanSalapat
IRC: NathanS21
In-game: NathanS21
Location: Bigsby Texas
Contact:

Re: Post your modding questions here

by Nathan.S » Post

Doubtless I'm just an idiot but can somebody tell me what is wrong with this?

Code: Select all

if inv:contains_item('fuel', 'group:tree') then
It works just fine for non-groups, but I want to support multiple fuels as inputs in a smoker I'm making. I suppose I could just do a chain of if statements but a group would be quicker and easier.
I record Minetest videos, Mod reviews, Modding tutorials, and Lets plays.
Check out my website, and brand new Minetest Modding Course

User avatar
kaeza
Moderator
Posts: 2162
Joined: Thu Oct 18, 2012 05:00
GitHub: kaeza
IRC: kaeza diemartin blaaaaargh
In-game: kaeza
Location: Montevideo, Uruguay
Contact:

Re: Post your modding questions here

by kaeza » Post

Note: UNTESTED:

Code: Select all

local function is_item_in_group(itemname, group)
  local def = minetest.registered_items[name]
  if not def then return end
  return (def.groups and (def.groups[group] or 0)>0)
end
-- In your code (this assumes "fuel" inv only has a single slot):
-- ...
local item = inv:get_stack("fuel", 1)
local fuel_groups = { "tree", "wood", "oil", "radiactive" } -- Groups considered "fuel"
if item and (not item:is_empty()) then
  for _, g in ipairs(fuel_groups) do
    if is_item_in_group(item:get_name(), g) then
      -- We found some fuel. Do something with it.
      return
    end
  end
end
-- ...
Adapt as necessary.

Of course, the proper solution would be to implement group resolution or whatever in `contains_item`.
Your signature is not the place for a blog post. Please keep it as concise as possible. Thank you!

Check out my stuff! | Donations greatly appreciated! PayPal

User avatar
Nathan.S
Member
Posts: 1147
Joined: Wed Sep 24, 2014 17:47
GitHub: NathanSalapat
IRC: NathanS21
In-game: NathanS21
Location: Bigsby Texas
Contact:

Re: Post your modding questions here

by Nathan.S » Post

Thank you so much kaeza, this looks like it should work. I just want people to be able to use logs, so I'll just be using the tree group. I tried just making a table and doing a if in table, which I know would work in python, but unfortunately LUA doesn't have that same feature.
I record Minetest videos, Mod reviews, Modding tutorials, and Lets plays.
Check out my website, and brand new Minetest Modding Course

minetestcr
Member
Posts: 58
Joined: Fri Feb 13, 2015 21:31

Re: Post your modding questions here

by minetestcr » Post

Hello!

Is there a way to have one user in creative mode while the others are not? It would be the server admin in creative mode, and the players in survival.

thanks.

User avatar
benrob0329
Member
Posts: 1341
Joined: Thu Aug 06, 2015 22:39
GitHub: Benrob0329
IRC: benrob0329
In-game: benrob03
Location: Michigan
Contact:

Re: Post your modding questions here

by benrob0329 » Post

Unified Inventory has a creative priv, that could work.

minetestcr
Member
Posts: 58
Joined: Fri Feb 13, 2015 21:31

Re: Post your modding questions here

by minetestcr » Post

benrob0329 wrote:Unified Inventory has a creative priv, that could work.

Thanks benrob0329.

User avatar
BrunoMine
Member
Posts: 1082
Joined: Thu Apr 25, 2013 17:29
GitHub: BrunoMine
Location: SP-Brasil
Contact:

Re: Post your modding questions here

by BrunoMine » Post

how to identify the lag of a client. I do not care only server lag, but each client individually.

User avatar
Semmett9
Member
Posts: 157
Joined: Sun Oct 07, 2012 13:48
Location: Gallifrey
Contact:

Re: Post your modding questions here

by Semmett9 » Post

How to activate a file if a mod is installed?

Is they a way to activate a file or bit of code if a mod is installed.

I have just mad a mod called "Beer_Test" and I’m currently working on a new mod "Farm_Test". Is they a way for me to add a line of code which looks for a mod called "Beer_Test"; and if it finds it will then activate some code which connects the two mods together.

Many Thanks

User avatar
kaeza
Moderator
Posts: 2162
Joined: Thu Oct 18, 2012 05:00
GitHub: kaeza
IRC: kaeza diemartin blaaaaargh
In-game: kaeza
Location: Montevideo, Uruguay
Contact:

Re: Post your modding questions here

by kaeza » Post

You need to add a file named `depends.txt` to the `farm_test` mod (if it doesn't already have one), and add this line to the file:

Code: Select all

beer_test?
This ensures the `beer_test` mod gets loaded first if found, but the mod is not required (i.e. it is optional).

Then, in `farm_test/init.lua` (or wherever appropriate), you use code like this:

Code: Select all

if minetest.get_modpath("beer_test") then
  -- beer_test is installed. Add some glue code, extra items, etc. here.
end
Your signature is not the place for a blog post. Please keep it as concise as possible. Thank you!

Check out my stuff! | Donations greatly appreciated! PayPal

Joz
Member
Posts: 41
Joined: Fri Oct 25, 2013 21:37

Re: Post your modding questions here

by Joz » Post

What is the best method to determine if the actual node has been initialised?

Themes: world generating, singlenode

When my lua map generators write nodes into an uninitialised chunk (for example trees, special caves, big pyramids…) the changes will be overridden when the on_register function of that chunk is called. There will be cut trees and leaf hanging in the air decaying.

So I have to know which nodes have been placed by a map generator. Is this possible? I tried it with testing if a node's id is not == minetest.get_content_id("ignore") but no node had this id. I also tried the same with …content_id("air") but there were still many empty chunks.

Thanks in advance!

User avatar
ArguablySane
Member
Posts: 116
Joined: Sun Oct 12, 2014 21:29

Re: Post your modding questions here

by ArguablySane » Post

Does anyone know of a fast way to hash 2 or more numbers together in Lua such that the result is deterministic, depends on the order of the parameters, and has a reasonably low probability of collisions?
Almost any standard hash function would be fine, but Lua 5.1 doesn't even support bitwise operators which rather limits my options.

The reason I need this is that I want to generate deterministic seeds from xyz coordinates and edges in a graph. It was incredibly easy to throw together a proof-of-concept cave generator in Python, but now that I'm trying to port it to Lua I'm fighting against awkward syntax and missing features.

The best idea I have had so far is to use minetest's PRNG with a function like:

Code: Select all

local function hash(n1,n2)
  local prng = PseudoRandom(n1)
  local n3 = prng.next() + n2
  prng = PseudoRandom(n3)
  return prng.next()
end
but creating a new PRNG object for every number I want to hash just seems horribly inefficient.
The above post and any ideas expressed therein are released to the public domain under a Creative Commons CC0 license.

User avatar
rubenwardy
Moderator
Posts: 6972
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: Bristol, United Kingdom
Contact:

Re: Post your modding questions here

by rubenwardy » Post

Isn't Minetest. Serialise position for this purpose?
Renewed Tab (my browser add-on) | Donate | Mods | Minetest Modding Book

Hello profile reader

User avatar
ArguablySane
Member
Posts: 116
Joined: Sun Oct 12, 2014 21:29

Re: Post your modding questions here

by ArguablySane » Post

rubenwardy wrote:Isn't Minetest. Serialise position for this purpose?
Is it? Can PseudoRandom(seed) accept a string as its seed, and will it use the entire string rather than just truncating it? If so, that would simplify things massively.
The above post and any ideas expressed therein are released to the public domain under a Creative Commons CC0 license.

User avatar
rubenwardy
Moderator
Posts: 6972
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: Bristol, United Kingdom
Contact:

Re: Post your modding questions here

by rubenwardy » Post

wrong name, it's minetest.hash_node_position({x=,y=,z=})

http://rubenwardy.com/minetest_modding_ ... .html#misc
Renewed Tab (my browser add-on) | Donate | Mods | Minetest Modding Book

Hello profile reader

Locked

Who is online

Users browsing this forum: No registered users and 3 guests