<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://olddev.minetest.org/index.php?action=history&amp;feed=atom&amp;title=User%3AHybrid_Dog</id>
	<title>User:Hybrid Dog - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://olddev.minetest.org/index.php?action=history&amp;feed=atom&amp;title=User%3AHybrid_Dog"/>
	<link rel="alternate" type="text/html" href="https://olddev.minetest.org/index.php?title=User:Hybrid_Dog&amp;action=history"/>
	<updated>2026-04-15T09:49:52Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.38.7</generator>
	<entry>
		<id>https://olddev.minetest.org/index.php?title=User:Hybrid_Dog&amp;diff=364&amp;oldid=prev</id>
		<title>&gt;ROllerozxa at 19:45, 25 January 2023</title>
		<link rel="alternate" type="text/html" href="https://olddev.minetest.org/index.php?title=User:Hybrid_Dog&amp;diff=364&amp;oldid=prev"/>
		<updated>2023-01-25T19:45:44Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== various ==&lt;br /&gt;
performance test shows&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
	local t0 = benchmark_function(function()&lt;br /&gt;
		for i = 1,1000 do&lt;br /&gt;
			local v = math.pow(2, i)&lt;br /&gt;
		end&lt;br /&gt;
	end)&lt;br /&gt;
&lt;br /&gt;
	local t1 = benchmark_function(function()&lt;br /&gt;
		local ln2 = math.log(2)&lt;br /&gt;
		for i = 1,1000 do&lt;br /&gt;
			local v = math.exp(i * ln2)&lt;br /&gt;
		end&lt;br /&gt;
	end)&amp;lt;/source&amp;gt;&lt;br /&gt;
the exp thing is faster by the factor 1.37&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
== minetest.on_place ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;source&amp;gt;minetest.on_place(nodename, func)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
=== Description ===&lt;br /&gt;
This changes on_place of a node after it was defined.&amp;lt;br/&amp;gt;&lt;br /&gt;
It is not implemented into minetest but can be added via mod(s):&lt;br /&gt;
&amp;lt;source&amp;gt;minetest.on_place = minetest.on_place or function(name, func)&lt;br /&gt;
	local previous_on_place = minetest.registered_nodes[name].on_place&lt;br /&gt;
	minetest.override_item(name, {&lt;br /&gt;
		on_place = function(...)&lt;br /&gt;
			if func(...) then&lt;br /&gt;
				return previous_on_place(...)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	})&lt;br /&gt;
end&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
==== nodename ====&lt;br /&gt;
The name of the node which should become changed&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
==== func ====&lt;br /&gt;
should return true if the node becomes set&lt;br /&gt;
&amp;lt;source&amp;gt;function(itemstack, placer, pointed_thing)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;source&amp;gt;minetest.on_place(&amp;quot;hydro:growlamp&amp;quot;, function(itemstack, placer, pointed_thing)&lt;br /&gt;
	if not pointed_thing then&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
	local pos = minetest.get_pointed_thing_position(pointed_thing, true)&lt;br /&gt;
	if not pos then&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
	local nd_above = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name&lt;br /&gt;
	local nd_above_info = minetest.registered_nodes[nd_above]&lt;br /&gt;
	if nd_above == &amp;quot;air&amp;quot;&lt;br /&gt;
	or nd_above == &amp;quot;hydro:growlamp&amp;quot;&lt;br /&gt;
	or not nd_above_info.walkable&lt;br /&gt;
	or nd_above_info.buildable_to then&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
== minetest key press and release functions ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;source&amp;gt;minetest.register_on_key_press(func(player, key))&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source&amp;gt;minetest.register_on_key_release(func(player, key))&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
These functions get executed when a player presses or releases a key.&amp;lt;br&amp;gt;&lt;br /&gt;
They're not implemented into minetest but can be added via mod(s):&lt;br /&gt;
&amp;lt;source&amp;gt;local on_key_releases,nr = {},0&lt;br /&gt;
function minetest.register_on_key_release(func)&lt;br /&gt;
	nr = nr+1&lt;br /&gt;
	on_key_releases[nr] = func&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local on_key_presses,np = {},0&lt;br /&gt;
function minetest.register_on_key_press(func)&lt;br /&gt;
	np = np+1&lt;br /&gt;
	on_key_presses[np] = func&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local playerkeys = {}&lt;br /&gt;
minetest.register_globalstep(function()&lt;br /&gt;
	for _,player in pairs(minetest.get_connected_players()) do&lt;br /&gt;
		local last_keys = playerkeys[player:get_player_name()]&lt;br /&gt;
		for key,stat in pairs(player:get_player_control()) do&lt;br /&gt;
			if stat then&lt;br /&gt;
				if not last_keys[key] then&lt;br /&gt;
					for i = 1,np do&lt;br /&gt;
						on_key_presses[i](player, key)&lt;br /&gt;
					end&lt;br /&gt;
					last_keys[key] = true&lt;br /&gt;
				end&lt;br /&gt;
			elseif last_keys[key] then&lt;br /&gt;
				for i = 1,nr do&lt;br /&gt;
					on_key_releases[i](player, key)&lt;br /&gt;
				end&lt;br /&gt;
				last_keys[key] = false&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
minetest.register_on_joinplayer(function(player)&lt;br /&gt;
	playerkeys[player:get_player_name()] = {}&lt;br /&gt;
end)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
==== player ====&lt;br /&gt;
The player who pressed the key&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
==== key ====&lt;br /&gt;
A string, the released or pressed key, see the get_player_control at Player.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&amp;lt;source&amp;gt;-- tell the player which keys he/she/it presses and releases&lt;br /&gt;
&lt;br /&gt;
minetest.register_on_key_release(function(player, key)&lt;br /&gt;
	minetest.chat_send_player(player:get_player_name(), &amp;quot;you released &amp;quot;..key)&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
minetest.register_on_key_press(function(player, key)&lt;br /&gt;
	minetest.chat_send_player(player:get_player_name(), &amp;quot;you keydownd &amp;quot;..key)&lt;br /&gt;
end)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mods ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== vector_extras ===&lt;br /&gt;
&lt;br /&gt;
Note that this is very outdated. The documentation is now at [https://github.com/HybridDog/vector_extras].&lt;br /&gt;
&lt;br /&gt;
Those are added as fields of the vector table, e.g. vector.pos_to_string(pos)&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible sortable&amp;quot;&lt;br /&gt;
! Function&lt;br /&gt;
! Return value&lt;br /&gt;
! Comments&lt;br /&gt;
! Status&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;pos_to_string(pos)&amp;lt;/source&amp;gt;&lt;br /&gt;
| string&lt;br /&gt;
| similar to minetest.pos_to_string, but better readable in my opinion&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;line([pos, dir[, range][, alt)&amp;lt;/source&amp;gt;&lt;br /&gt;
| table of vectors&lt;br /&gt;
| dir can be following:&lt;br /&gt;
* a direction&lt;br /&gt;
* a position (range not needed)&lt;br /&gt;
if alt then the old path calculation is used&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;fine_line([pos, dir[, range], scale])&amp;lt;/source&amp;gt;&lt;br /&gt;
| table of vectors&lt;br /&gt;
|&lt;br /&gt;
* like the old vector.line but more precise&lt;br /&gt;
* needed for not round positions&lt;br /&gt;
* try using minetest.line_of_sight instead&lt;br /&gt;
| works but&amp;lt;br/&amp;gt;old and slow&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;twoline(x, y)&amp;lt;/source&amp;gt;&lt;br /&gt;
| table&lt;br /&gt;
|&lt;br /&gt;
* returns sth like {{0,0}, {0,1}}&lt;br /&gt;
* used for a 2d line&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;threeline(x, y, z)&amp;lt;/source&amp;gt;&lt;br /&gt;
| table&lt;br /&gt;
|&lt;br /&gt;
* returns sth like {{0,0,0}, {0,1,0}}&lt;br /&gt;
* used for a 3d line&lt;br /&gt;
* x, y and z should be round&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;sort(ps, [preferred_coords])&amp;lt;/source&amp;gt;&lt;br /&gt;
| nil&lt;br /&gt;
| ps, which gets changed, is a list of vectors,&lt;br /&gt;
which become sorted by the coord in the order of preferred_coords&lt;br /&gt;
| untested&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;scalar(v1, v2)&amp;lt;/source&amp;gt;&lt;br /&gt;
| number&lt;br /&gt;
| v1 and v2 are vectors, returns scalar product&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;cross(v1, v2)&amp;lt;/source&amp;gt;&lt;br /&gt;
| vector&lt;br /&gt;
| v1 and v2 are vectors, returns cross product&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;plane(ps)&amp;lt;/source&amp;gt;&lt;br /&gt;
| table of vectors&lt;br /&gt;
| ps is a table of three vectors&lt;br /&gt;
returns a list of vectors which make a filled triangle plane together&lt;br /&gt;
| unfinished&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;straightdelay([s, v[, a)&amp;lt;/source&amp;gt;&lt;br /&gt;
| number&lt;br /&gt;
|&lt;br /&gt;
* s = length&lt;br /&gt;
* v = velocity&lt;br /&gt;
* a = acceleration (optional)&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;sun_dir(t)&amp;lt;/source&amp;gt;&lt;br /&gt;
| vector&lt;br /&gt;
|&lt;br /&gt;
* t = timeofday&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;inside(pos, minp, maxp)&amp;lt;/source&amp;gt;&lt;br /&gt;
| bool&lt;br /&gt;
| returns true if pos is inside or on the corners of minp and maxp&lt;br /&gt;
| untested&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;minmax(p1, p2)&amp;lt;/source&amp;gt;&lt;br /&gt;
| vector, vector&lt;br /&gt;
| the first vector's x, y and z are smaller than the second one's&lt;br /&gt;
| untested&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;move(p1, p2, s)&amp;lt;/source&amp;gt;&lt;br /&gt;
| vector&lt;br /&gt;
|&lt;br /&gt;
* s = length&lt;br /&gt;
* moves s to p2 from p1&lt;br /&gt;
* made for rubenwardy&lt;br /&gt;
| untested&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;from_number(i)&amp;lt;/source&amp;gt;&lt;br /&gt;
| vector&lt;br /&gt;
| returns {x=i, y=i, z=i}&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;explosion_table(r)&amp;lt;/source&amp;gt;&lt;br /&gt;
| table&lt;br /&gt;
|&lt;br /&gt;
* r = radius&lt;br /&gt;
* returns sth like &amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;{{pos1, true}, {pos2}}&amp;lt;/source&amp;gt;&lt;br /&gt;
* using explosion_perlin instead is recommended&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;explosion_perlin(rmin, rmax[, nparams])&amp;lt;/source&amp;gt;&lt;br /&gt;
| table&lt;br /&gt;
| it is used to make perlin noise surface on spheres, which looks good for explosions&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;circle(r)&amp;lt;/source&amp;gt;&lt;br /&gt;
| table of vectors&lt;br /&gt;
|&lt;br /&gt;
* r = radius&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;ring(r)&amp;lt;/source&amp;gt;&lt;br /&gt;
| table of vectors&lt;br /&gt;
|&lt;br /&gt;
* r = radius&lt;br /&gt;
* r can be float&lt;br /&gt;
* each positions &amp;quot;touch&amp;quot; their next ones&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;chunkcorner(pos)&amp;lt;/source&amp;gt;&lt;br /&gt;
| vector&lt;br /&gt;
| should return the chunkcorner near pos&lt;br /&gt;
| could work&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;point_distance_minmax(p1, p2)&amp;lt;/source&amp;gt;&lt;br /&gt;
| 2 numbers&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;collision(p1, p2)&amp;lt;/source&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;get_data_from_pos(tab, z,y,x)&amp;lt;/source&amp;gt;&lt;br /&gt;
| tab[z][y][x] or nil&lt;br /&gt;
| used to get stored information in a table about these coords&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;set_data_to_pos(tab, z,y,x, data)&amp;lt;/source&amp;gt;&lt;br /&gt;
| nil&lt;br /&gt;
| used to store information in a table about these coords&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;set_data_to_pos_optional(tab, z,y,x, data)&amp;lt;/source&amp;gt;&lt;br /&gt;
| nil&lt;br /&gt;
| runs set_data_from_pos if get_data_from_pos returned nil there&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;remove_data_from_pos(tab, z,y,x)&amp;lt;/source&amp;gt;&lt;br /&gt;
| nil&lt;br /&gt;
| used to remove information from a table about these coords&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;get_data_pos_table(tab)&amp;lt;/source&amp;gt;&lt;br /&gt;
| table&lt;br /&gt;
|&lt;br /&gt;
* tab was used by set_data_to_pos etc.&lt;br /&gt;
* returns {{z,y,x, v}, {z,y,x, v}, …}, {x=minx, y=miny, z=minz}, {x=maxx, y=maxy, z=maxz}, count&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;update_minp_maxp(minp, maxp, pos)&amp;lt;/source&amp;gt;&lt;br /&gt;
| nil&lt;br /&gt;
| changes minp and maxp to exceed their borders&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;quickadd(pos[, z,y,x])&amp;lt;/source&amp;gt;&lt;br /&gt;
| nil&lt;br /&gt;
| adds those to pos', works more than 4.3 times as fast as using vector.add&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;unpack(pos)&amp;lt;/source&amp;gt;&lt;br /&gt;
| 3 numbers&lt;br /&gt;
| returns pos.z, pos.y, pos.x&lt;br /&gt;
| works&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;source enclose=&amp;quot;none&amp;quot;&amp;gt;zero&amp;lt;/source&amp;gt;&lt;br /&gt;
| {x=0, y=0, z=0}&lt;br /&gt;
| not a function&lt;br /&gt;
| works&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;/div&gt;</summary>
		<author><name>&gt;ROllerozxa</name></author>
	</entry>
</feed>