-
Notifications
You must be signed in to change notification settings - Fork 10
/
[KAM] Isometric Box.lua
293 lines (239 loc) · 9.04 KB
/
[KAM] Isometric Box.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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
--[[---------------------------------------------------------------------
__
__ /\ \__ __
/\_\ ____ ___ ___ ___ __\ \ ,_\ _ __ /\_\ ___
\/\ \ /',__\ / __`\ /' __` __`\ /'__`\ \ \/ /\`'__\/\ \ /'___\
\ \ \/\__, `\/\ \L\ \/\ \/\ \/\ \/\ __/\ \ \_\ \ \/ \ \ \/\ \__/
\ \_\/\____/\ \____/\ \_\ \_\ \_\ \____\\ \__\\ \_\ \ \_\ \____\
\/_/\/___/ \/___/ \/_/\/_/\/_/\/____/ \/__/ \/_/ \/_/\/____/
__ _ __
/\ \ /' \ /'__`\
\ \ \____ ___ __ _ /\_, \ /\ \/\ \
\ \ '__`\ / __`\/\ \/'\ \/_/\ \ \ \ \ \ \
\ \ \L\ \/\ \L\ \/> </ \ \ \ __\ \ \_\ \
\ \_,__/\ \____//\_/\_\ \ \_\/\_\\ \____/
\/___/ \/___/ \//\/_/ \/_/\/_/ \/___/
ISOMETRIC BOX GENERATOR 1.0 for Aseprite (https://aseprite.org)
Project page: https://darkwark.itch.io/isobox-for-aseprite
by Kamil Khadeyev (@darkwark)
Twitter: http://twitter.com/darkwark
Dribbble: http://dribbble.com/darkwark
Website: http://darkwark.com
(c) 2018, November
All rights reserved or something
Features:
+ Customize X, Y and Z size of the box
+ Customize colors for each side of the box
+ Custom Stroke and Highlight colors
+ Two types of the box: 3px and 2px corner
Requirements:
+ Aseprite 1.2.10-beta2
+ Color Mode: RGBA
Installation:
+ Open Aseprite
+ Go to `File → Scripts → Open Scripts Folder`
+ Place downloaded LUA script into opened directory
+ Restart Aseprite
Usage:
+ Go to `File → Scripts → [KAM] Isometric Box` to run the script
+ You can also setup a custom hotkey under `Edit → Keyboard Shortcuts`
-----------------------------------------------------------------------]]
---------------------------------------
-- USER DEFAULTS --
---------------------------------------
local c = app.fgColor;
-- Default colors:
local colors = {
stroke = Color{h=0, s=0, v=0, a=255},
top = app.fgColor,
left = Color{h=c.hsvHue, s=c.hsvSaturation+0.3, v=c.hsvValue-0.1, a=255},
right = Color{h=c.hsvHue, s=c.hsvSaturation+0.3, v=c.hsvValue-0.4, a=255},
highlight = Color{h=c.hsvHue, s=c.hsvSaturation-0.2, v=c.hsvValue+0.2, a=255}
}
-- Use 3px corner by default:
local use3pxCorner = false
-- Default Max Sizes:
local maxSize = {
x = math.floor(app.activeSprite.width/4),
y = math.floor(app.activeSprite.width/4),
z = math.floor(app.activeSprite.height/2)
}
---------------------------------------
-- Colors Utility --
---------------------------------------
local function colorAsPixel(color)
return app.pixelColor.rgba(color.red, color.green, color.blue, color.alpha)
end
local function isColorEqual(a, b)
local pc = app.pixelColor
return pc.rgbaR(a) == pc.rgbaR(b) and
pc.rgbaG(a) == pc.rgbaG(b) and
pc.rgbaB(a) == pc.rgbaB(b) and
pc.rgbaA(a) == pc.rgbaA(b)
end
local function isColorEqualAt(x, y, color)
local pc = app.pixelColor
local pickedColor = app.activeImage:getPixel(x, y)
return isColorEqual(pickedColor, color)
end
---------------------------------------
-- Flood Fill --
-- Paint Bucket Tool implementation --
---------------------------------------
local function floodFill(x, y, targetColor, replacementColor)
if isColorEqual(targetColor, replacementColor) then return end
if not isColorEqualAt(x, y, targetColor) then return end
app.activeImage:putPixel(x, y, replacementColor)
floodFill(x+1, y, targetColor, replacementColor)
floodFill(x-1, y, targetColor, replacementColor)
floodFill(x, y+1, targetColor, replacementColor)
floodFill(x, y-1, targetColor, replacementColor)
end
---------------------------------------
-- BASIC LINES --
---------------------------------------
local function hLine(color, x, y, len)
-- Horizontal Line
for i = 1, len do
app.activeImage:putPixel(x+i, y, color)
end
end
local function vLine(color, x, y, len)
-- Vertical Line
for i = 1, len do
app.activeImage:putPixel(x, y+i, color)
end
end
---------------------------------------
-- ISOMETRIC LINES --
---------------------------------------
--TODO: Compile these functions into one universal isoLine(direction)
local function isoLineDownRight(color, x, y, len)
for i=0,len do
x1 = i*2
x2 = x1+1
app.activeImage:putPixel(x+x1, y+i, color)
app.activeImage:putPixel(x+x2, y+i, color)
end
end
local function isoLineDownLeft(color, x, y, len)
for i=0,len do
x1 = i*2
x2 = x1+1
app.activeImage:putPixel(x-x1, y+i, color)
app.activeImage:putPixel(x-x2, y+i, color)
end
end
local function isoLineUpRight(color, x, y, len)
for i=0,len do
x1 = i*2
x2 = x1+1
app.activeImage:putPixel(x+x1, y-i, color)
app.activeImage:putPixel(x+x2, y-i, color)
end
end
local function isoLineUpLeft(color, x, y, len)
for i=0,len do
x1 = i*2
x2 = x1+1
app.activeImage:putPixel(x-x1, y-i, color)
app.activeImage:putPixel(x-x2, y-i, color)
end
end
---------------------------------------
-- FINAL CUBE --
---------------------------------------
local function drawCube(type, xSize, ySize, zSize, color)
--[[
Dimensions:
X: right side
Y: left side
Z: is height
Type can be 1 or 2:
1 is for 3px corner
2 is for 2px corner
]]--
local centerX = math.floor(app.activeSprite.width/2)
local centerY = math.floor(app.activeSprite.height/2)
local a = (type == 1) and 0 or 1
local b = (type == 1) and 1 or 0
--top plane
isoLineUpRight(color, centerX-a, centerY, xSize) --bottom right
isoLineUpLeft(color, centerX, centerY, ySize) --bottom left
isoLineUpLeft(color, centerX+xSize*2+b, centerY-xSize, ySize) --top right
isoLineUpRight(color, centerX-ySize*2-1, centerY-ySize, xSize) --top left
--bottom plane
isoLineUpRight(color, centerX-a, centerY+zSize, xSize) --right
isoLineUpLeft(color, centerX, centerY+zSize, ySize) --left
--vertical lines
vLine(color, centerX-a, centerY, zSize) --middle
vLine(color, centerX-ySize*2-1, centerY-ySize, zSize) --left
vLine(color, centerX+xSize*2+b, centerY-xSize, zSize) --right
end
------------ Adding Colors: ------------
local function fillCubeSides(topColor, leftColor, rightColor)
local centerX = math.floor(app.activeSprite.width/2)
local centerY = math.floor(app.activeSprite.height/2)
local TRANSPARENT_COLOR = app.pixelColor.rgba(0, 0, 0, 0)
-- Top Color
floodFill(centerX, centerY-1, TRANSPARENT_COLOR, colorAsPixel(topColor))
-- Left Color
floodFill(centerX-2, centerY+1, TRANSPARENT_COLOR, colorAsPixel(leftColor))
-- Right Color
floodFill(centerX+1, centerY+1, TRANSPARENT_COLOR, colorAsPixel(rightColor))
end
local function addHighlight(type, xSize, ySize, zSize, color)
local centerX = math.floor(app.activeSprite.width/2)
local centerY = math.floor(app.activeSprite.height/2)
-- TYPE1 is for 3px in the middle
-- TYPE2 is for 2px in the middle
local alt = (type == 1) and 0 or 1
isoLineUpRight(color, centerX-alt, centerY, xSize-1)
isoLineUpLeft(color, centerX, centerY, ySize-1)
vLine(color, centerX-alt, centerY, zSize-1)
app.activeImage:putPixel(centerX-alt, centerY, app.pixelColor.rgba(255, 255, 255, 255))
end
---------------------------------------
-- LAYER MANAGEMENT --
---------------------------------------
local function newLayer(name)
s = app.activeSprite
lyr = s:newLayer()
lyr.name = name
s:newCel(lyr, 1)
return lyr
end
---------------------------------------
-- USER INTERFACE --
---------------------------------------
local dlg = Dialog("[KAM] Isometric Box")
dlg :separator{ text="Size:" }
:slider {id="ySize", label="Left:", min=1, max=maxSize.y, value=5}
:slider {id="xSize", label="Right:", min=1, max=maxSize.x, value=5}
:slider {id="zSize", label="Height:", min=3, max=maxSize.z, value=10}
:separator{ text="Colors:" }
:color {id="color", label="Stroke:", color = colors.stroke}
:color {id="topColor", label="Top:", color = colors.top}
:color {id="leftColor", label="Left:", color = colors.left}
:color {id="rightColor", label="Right:", color = colors.right}
:color {id="highlightColor", label="Highlight:", color = colors.highlight}
:separator()
:radio {id="typeOne", label="Corner:", text="3 px", selected=use3pxCorner}
:radio {id="typeTwo", text="2 px", selected=not use3pxCorner}
:separator()
:button {id="ok", text="Add Box",onclick=function()
local data = dlg.data
app.transaction(function()
local cubeType = data.typeOne and 1 or 2
newLayer("Cube("..data.xSize.." "..data.ySize.." "..data.zSize..")")
drawCube(cubeType, data.xSize, data.ySize, data.zSize, data.color)
fillCubeSides(data.topColor, data.leftColor, data.rightColor)
addHighlight(cubeType, data.xSize, data.ySize, data.zSize, data.highlightColor)
end)
--Refresh screen
app.command.Undo()
app.command.Redo()
end
}
:show{wait=false}
---------------------------------------