-
Notifications
You must be signed in to change notification settings - Fork 0
/
shapes.lua
194 lines (162 loc) · 4.61 KB
/
shapes.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
if not table.merge then
function table.merge( target, ... )
for i=1, table.getn( arg ) do
for k, v in pairs( arg[i] ) do
target[k] = v
end
end
return target
end
end
function bresenham( v1, v2 )
local ov = v1
v1 = {0, 0, 0}
v2 = {v2[1] - ov[1], v2[2] - ov[2], v2[3] - ov[3]}
local x0, y0, z0, x1, y1, z1 = v1[1], v1[2], v1[3], v2[1], v2[2], v2[3]
local dx, dy = math.abs( v2[1] )
--[[
function line(x0, y0, x1, y1)
dx := abs(x1-x0)
dy := abs(y1-y0)
if x0 < x1 then sx := 1 else sx := -1
if y0 < y1 then sy := 1 else sy := -1
err := dx-dy
loop
setPixel(x0,y0)
if x0 = x1 and y0 = y1 exit loop
e2 := 2*err
if e2 > -dy then
err := err - dy
x0 := x0 + sx
end if
if e2 < dx then
err := err + dx
y0 := y0 + sy
end if
end loop
--]]
end
shape = {}
function shape.line( t, opts )
opts = table.merge( {
v1 = false,
v2 = {0, 0, 0},
}, opts )
local state = t( 'getState' )
if not opts.v1 then
return true
end
if not opts.v2 then
opts.v2 = v1
opts.v1 = stateToVert( state )
end
end
-- a plain line, only changing in one direction.
-- e.g. 0,0,0 to 0,10,0
function shape.straightline( t, opts )
opts = table.merge( {
v1 = false,
dir = false,
dist = 0,
retrymove = nil,
before = function() end,
after = function() end,
move = function() return t( 'forward' ) end,
}, opts )
if opts.v1 == false then
opts.v1 = stateToVert( t( 'getState' ) )
end
if opts.dir == false then
opts.dir = opts.v1[4]
end
retrymove( t, opts.v1, { retry = opts.retrymove } )
faceDirection( t, opts.dir )
--starting at 1 so that if they say go 1, I get one call of the move callbacks
for i=1, opts.dist do
if opts.before() == false then return false end
if opts.move( t ) == false then return false end
if opts.after() == false then return false end
end
return true
end
function shape.rect( t, opts )
opts = table.merge( {
v1 = false,
v2 = false,
filled = false,
onrect = function() end,
}, opts )
if opts.v2 == false then return true end
if opts.v1 == false then opts.v1 = stateToVert( t( 'getState' ) ) end
local samex = false
local ret = true
if opts.v1[1] >= opts.v2[1] then
samex = true
opts.v1 = table.merge( {}, opts.v1, {opts.v2[1]} )
end
if opts.v1[2] >= opts.v2[2] then
--if samex then return true end
if samex then
--special case to handle center block
ret = ret and shape.straightline( t, table.merge( {}, opts, {
v1 = opts.v1,
dir = 0,
dist = 1,
}))
if ret and opts.onrect() == false then return false end
return ret
end
opts.v2 = table.merge( {}, opts.v1, {[2] = opts.v2[2]} )
end
ret = ret and shape.straightline( t, table.merge( {}, opts, {
v1 = opts.v1,
dir = 0,
dist = opts.v2[2] - opts.v1[2],
}))
ret = ret and shape.straightline( t, table.merge( {}, opts, {
v1 = false,
dir = 1,
dist = opts.v2[1] - opts.v1[1],
}))
ret = ret and shape.straightline( t, table.merge( {}, opts, {
v1 = false,
dir = 2,
dist = opts.v2[2] - opts.v1[2],
}))
ret = ret and shape.straightline( t, table.merge( {}, opts, {
v1 = false,
dir = 3,
dist = opts.v2[1] - opts.v1[1],
}))
if ret and opts.filled then
t( 'turnRight' )
if opts.onrect() == false then return false end
local curstate = t( 'getState' )
opts.v1 = {opts.v1[1] + 1, opts.v1[2] + 1, curstate.z, opts.v1[4]}
opts.v2 = {opts.v2[1] - 1, opts.v2[2] - 1, curstate.z, opts.v2[4]}
return shape.rect( t, opts )
end
return ret
end
function shape.pyramid( t, opts )
t( 'up' )
return shape.rect( t, table.merge( {
filled = true,
after = function()
t( 'placeDown' )
end,
onrect = function()
t( 'up' )
end
}, opts))
end
-- point a to point b with the fewest turns manhattan path
-- E.g. to do 0,0,0 to 3,5,7, it would
-- drive to 3,0,0 -> 3,5,0 -> 3,5,7
function shape.manline( t, opts )
end
--ctx may contain turtle settings, location of chests, inventory, etc.
--step is a callback to call on each step
--v1 and v2 define the volume of the cuboid
function shape.cuboid( t, ctx, step, v1, v2 )
end