-
Notifications
You must be signed in to change notification settings - Fork 8
/
circle.lua
142 lines (126 loc) · 3.67 KB
/
circle.lua
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
local function place_circle(player, pos, node)
local player_data = edit.player_data[player]
if
player:get_player_control().aux1 or
not player_data or
not player_data.circle_luaentity
or player_data.ignore_node_placement
then return end
local center = player_data.circle_luaentity._pos
center.y = pos.y
local radius = vector.distance(center, pos)
if radius < 1 then
minetest.set_node(pos, node)
return
else
minetest.remove_node(pos)
end
local radius_rounded = math.ceil(radius) + 1
local size = vector.new(radius_rounded * 2, 1, radius_rounded * 2)
if size.x * size.y * size.z > edit.max_operation_volume then
edit.display_size_error(player)
return
end
player_data.undo_schematic = edit.schematic_from_map(
vector.subtract(vector.round(center), vector.new(radius_rounded, 0, radius_rounded)),
size
)
player_data.ignore_node_placement = true -- Stop infinite recursion
-- Midpoint circle algorithm
local x = radius
local z = 0
if center.z % 1 ~= 0 then -- Is the marker in the middle of a node?
z = z + 0.5
end
while x >= z do
for factor_x = -1, 1, 2 do
for factor_z = -1, 1, 2 do
local factor = vector.new(factor_x, 1, factor_z)
local offset1 = vector.new(x, 0, z)
offset1 = vector.new(
offset1.x * factor.x,
offset1.y * factor.y,
offset1.z * factor.z )
local pos1 = vector.add(center, offset1)
edit.place_item_like_player(player, node, pos1)
local offset2 = vector.new(
offset1.z,
offset1.y,
offset1.x
)
local pos2 = vector.add(center, offset2)
edit.place_item_like_player(player, node, pos2)
end
end
z = z + 1
while z * z + x * x > radius * radius do
x = x - 1
end
end
player_data.ignore_node_placement = false
end
minetest.register_on_dignode(function(pos, oldnode, digger)
if not digger or not digger:is_player() then return end
return place_circle(digger, pos, {name = "air"}) or true
end)
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
if not placer then return end
return place_circle(placer, pos, newnode)
end)
local function circle_tool_on_place(itemstack, player, pointed_thing)
if not edit.on_place_checks(player) then return end
local d = edit.player_data[player]
if d.circle_luaentity then
d.circle_luaentity.object:remove()
end
local pos = edit.get_half_node_pointed_pos(player)
d.circle_luaentity = edit.add_marker("edit:circle", pos, player)
d.circle_hud = player:hud_add({
hud_elem_type = "text",
text = "CIRCLE MODE\n\nPunch the circle center to exit.\nPress the aux1 key (E) while placing to bypass.",
position = {x = 0.5, y = 0.8},
z_index = 100,
number = 0xffffff
})
end
minetest.register_tool("edit:circle",{
description = "Edit Circle",
tiles = {"edit_circle.png"},
inventory_image = "edit_circle.png",
range = 10,
groups = {edit_place_preview = 1,},
on_place = circle_tool_on_place,
on_secondary_use = circle_tool_on_place,
_edit_get_pointed_pos = function(player)
return edit.get_half_node_pointed_pos(player)
end,
})
minetest.register_entity("edit:circle", {
initial_properties = {
visual = "cube",
visual_size = { x = 1.1, y = 1.1},
physical = false,
collide_with_objects = false,
static_save = false,
use_texture_alpha = true,
glow = -1,
backface_culling = false,
hp_max = 1,
textures = {
"edit_circle.png",
"edit_circle.png",
"edit_circle.png",
"edit_circle.png",
"edit_circle.png",
"edit_circle.png",
},
},
on_deactivate = function(self)
local player_data = edit.player_data[self._placer]
if player_data then
player_data.circle_luaentity = nil
self._placer:hud_remove(player_data.circle_hud)
player_data.circle_hud = nil
end
end,
})