summaryrefslogtreecommitdiff
path: root/util_movement.lua
blob: f7c36ddcdcf5399d70c15d6a335e330149b9b0a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
digtron.move_node = function(pos, newpos, player_name)
	-- Moves nodes, preserving digtron metadata and inventory
	local node = minetest.get_node(pos)
	local node_def = minetest.registered_nodes[node.name]
	local oldnode = minetest.get_node(newpos)
	minetest.log("action", string.format("%s moves %s from (%d, %d, %d) to (%d, %d, %d), displacing %s", player_name, node.name, pos.x, pos.y, pos.z, newpos.x, newpos.y, newpos.z, oldnode.name))
	minetest.add_node(newpos, { name=node.name, param1=node.param1, param2=node.param2 })
	-- copy the metadata
	local oldmeta_table = minetest.get_meta(pos):to_table()
	local meta = minetest.get_meta(newpos)
	meta:from_table(oldmeta_table)
	meta:set_string("waiting", nil) -- If a controller moves another controller that's in the waiting state, clear the waiting state otherwise it might get stuck like that (we've moved it away from the target of the pending 'clear the waiting state' delegate call). That means you can run a digtron as fast as you want by rapidly clicking between two different controllers, but shhh - don't tell the player that.

	-- Move the little floaty entity inside the builders
	if minetest.get_item_group(node.name, "digtron") == 4 then
		digtron.update_builder_item(newpos)
	end
	
	if node_def.after_place_node then
		node_def.after_place_node(newpos)
	end
	
	-- remove node from old position
	minetest.remove_node(pos)
	if node_def.after_dig_node then
		node_def.after_dig_node(pos)
	end
end

digtron.move_digtron = function(facing, digtrons, extents, nodes_dug, player_name)
	-- move everything. Note! order is important or they'll step on each other, that's why this has complicated loops and filtering.
	-- Nodes are moved in a "caterpillar" pattern - front plane first, then next plane back, then next plane back, etc.
	-- positions in the digtron list will be updated when this method executes. Note that the inventories list shares
	-- references to the node position tables in the digtron list, so it will reflect the updates too.
	local dir = digtron.facedir_to_dir_map[facing]
	local increment
	local filter
	local index
	local target
	if dir == 1 then -- z+
		filter = "z"
		increment = -1
		index = extents.max_z
		target = extents.min_z
		extents.max_z = extents.max_z + 1
		extents.min_z = extents.min_z + 1
	elseif dir == 2 then -- x+
		filter = "x"
		increment = -1
		index = extents.max_x
		target = extents.min_x
		extents.max_x = extents.max_x + 1
		extents.min_x = extents.min_x + 1
	elseif dir == 3 then -- z-
		filter = "z"
		increment = 1
		index = extents.min_z
		target = extents.max_z
		extents.max_z = extents.max_z - 1
		extents.min_z = extents.min_z - 1
	elseif dir == 4 then -- x-
		filter = "x"
		increment = 1
		index = extents.min_x
		target = extents.max_x
		extents.max_x = extents.max_x - 1
		extents.min_x = extents.min_x - 1
	elseif dir == 5 then -- y-
		filter = "y"
		increment = 1
		index = extents.min_y
		target = extents.max_y
		extents.max_y = extents.max_y - 1
		extents.min_y = extents.min_y - 1
	elseif dir == 6 then -- y+
		filter = "y"
		increment = -1
		index = extents.max_y
		target = extents.min_y
		extents.max_y = extents.max_y + 1
		extents.min_y = extents.min_y + 1
	end

	while index ~= target + increment do
		for k, location in pairs(digtrons) do
			if location[filter] == index then
				local newpos = digtron.find_new_pos(location, facing)
				digtron.move_node(location, newpos, player_name)
				--By updating the digtron position table in-place we also update all the special node tables as well
				digtrons[k].x= newpos.x
				digtrons[k].y= newpos.y
				digtrons[k].z= newpos.z
				nodes_dug:set(newpos.x, newpos.y, newpos.z, false) -- we've moved a digtron node into this space, mark it so that we don't dig it.
			end
		end
		index = index + increment
	end
end