@iborymagic/aseprite-mcp 0.4.4 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.js +0 -0
- package/build/lua/templates/auto_crop_transparent.lua +23 -0
- package/build/lua/templates/export_layer_only.lua +41 -0
- package/build/lua/templates/export_tag_frames.lua +67 -0
- package/build/lua/templates/get_active_sprite_info.lua +19 -0
- package/build/lua/templates/get_frame_info.lua +24 -0
- package/build/lua/templates/get_is_layer_exists.lua +33 -0
- package/build/lua/templates/get_is_tag_exists.lua +25 -0
- package/build/lua/templates/get_layer_list.lua +31 -0
- package/build/lua/templates/get_palette_info.lua +34 -0
- package/build/lua/templates/get_selection_bounds.lua +24 -0
- package/build/lua/templates/get_tag_list.lua +25 -0
- package/build/lua/templates/merge_visible_layers.lua +24 -0
- package/build/lua/templates/normalize_animation_speed.lua +40 -0
- package/build/lua/templates/recolor_palette.lua +131 -0
- package/build/lua/templates/remove_layer_by_name.lua +38 -0
- package/package.json +6 -3
package/build/index.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
-- Auto-crops a sprite and saves the result.
|
|
2
|
+
-- Params:
|
|
3
|
+
-- saveOutput : string
|
|
4
|
+
|
|
5
|
+
local p = app.params
|
|
6
|
+
if not p or not p.saveOutput then
|
|
7
|
+
print("ERROR: saveOutput is required")
|
|
8
|
+
return
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
local sprite = app.activeSprite
|
|
12
|
+
|
|
13
|
+
if not sprite then
|
|
14
|
+
print("ERROR: No active sprite")
|
|
15
|
+
return
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
app.command.AutocropSprite()
|
|
19
|
+
|
|
20
|
+
sprite:saveAs(p.saveOutput)
|
|
21
|
+
|
|
22
|
+
sprite:close()
|
|
23
|
+
print("auto_crop_transparent script executed successfully")
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- Exports a single layer as a PNG file.
|
|
2
|
+
-- Params:
|
|
3
|
+
-- layerName : string
|
|
4
|
+
-- outputDir : string (must exist or will be created by Node side)
|
|
5
|
+
|
|
6
|
+
local p = app.params
|
|
7
|
+
if not p or not p.layerName or not p.outputDir then
|
|
8
|
+
print("ERROR: layerName and outputDir are required")
|
|
9
|
+
return
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
local sprite = app.activeSprite
|
|
13
|
+
|
|
14
|
+
if not sprite then
|
|
15
|
+
print("ERROR: No active sprite")
|
|
16
|
+
return
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
local target = nil
|
|
20
|
+
|
|
21
|
+
for _, layer in ipairs(sprite.layers) do
|
|
22
|
+
if layer.name == p.layerName then
|
|
23
|
+
target = layer
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
if not target then
|
|
28
|
+
print("ERROR: Layer not found: " .. p.layerName)
|
|
29
|
+
return
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
for _, layer in ipairs(sprite.layers) do
|
|
33
|
+
layer.isVisible = false
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
target.isVisible = true
|
|
37
|
+
|
|
38
|
+
sprite:saveAs(p.outputDir .. "/" .. p.layerName .. ".png")
|
|
39
|
+
|
|
40
|
+
sprite:close()
|
|
41
|
+
print("export_layer_only script executed successfully")
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
-- Exports only frames inside a specific tag as individual PNG files.
|
|
2
|
+
-- Params:
|
|
3
|
+
-- tag : string
|
|
4
|
+
-- outputDir : string (must exist or will be created by Node side)
|
|
5
|
+
-- filenamePrefix : string (optional, default "frame")
|
|
6
|
+
|
|
7
|
+
local p = app.params
|
|
8
|
+
|
|
9
|
+
if not p or not p.outputDir then
|
|
10
|
+
print("ERROR: outputDir is required")
|
|
11
|
+
return
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
local sprite = app.activeSprite
|
|
15
|
+
|
|
16
|
+
if not sprite then
|
|
17
|
+
print("ERROR: No active sprite")
|
|
18
|
+
return
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
local tagName = p.tag
|
|
22
|
+
if not tagName or tagName == "" then
|
|
23
|
+
print("ERROR: tag is required")
|
|
24
|
+
return
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
local outputDir = p.outputDir or "."
|
|
28
|
+
local prefix = p.filenamePrefix or "frame"
|
|
29
|
+
|
|
30
|
+
local tag = nil
|
|
31
|
+
for _, t in ipairs(sprite.tags) do
|
|
32
|
+
if t.name == tagName then
|
|
33
|
+
tag = t
|
|
34
|
+
break
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
if not tag then
|
|
39
|
+
print("ERROR: Tag not found: " .. tagName)
|
|
40
|
+
return
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
local startFrame = tag.fromFrame.frameNumber
|
|
44
|
+
local endFrame = tag.toFrame.frameNumber
|
|
45
|
+
|
|
46
|
+
for frameNumber = startFrame, endFrame do
|
|
47
|
+
local frameIndex = frameNumber - 1
|
|
48
|
+
|
|
49
|
+
local newSprite = Sprite(sprite.spec)
|
|
50
|
+
for i, layer in ipairs(sprite.layers) do
|
|
51
|
+
if i > 1 then
|
|
52
|
+
newSprite:newLayer(layer.name)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
local cel = layer:cel(frameIndex)
|
|
56
|
+
if cel then
|
|
57
|
+
newSprite:newCel(newSprite.layers[i], newSprite.frames[1], cel.image, cel.position)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
local filename = string.format("%s/%s-%04d.png", outputDir, prefix, frameNumber)
|
|
62
|
+
newSprite:saveAs(filename)
|
|
63
|
+
newSprite:close()
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
sprite:close()
|
|
67
|
+
print("export_tag_frames script executed successfully")
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-- Returns information about the active sprite.
|
|
2
|
+
-- Params:
|
|
3
|
+
-- none
|
|
4
|
+
|
|
5
|
+
local sprite = app.activeSprite
|
|
6
|
+
|
|
7
|
+
if not sprite then
|
|
8
|
+
print("ERROR: No active sprite")
|
|
9
|
+
return
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
print(json.encode({
|
|
13
|
+
width = sprite.width,
|
|
14
|
+
height = sprite.height,
|
|
15
|
+
colorMode = sprite.colorMode == ColorMode.RGB and "rgb"
|
|
16
|
+
or sprite.colorMode == ColorMode.INDEXED and "indexed"
|
|
17
|
+
or "grayscale",
|
|
18
|
+
frameCount = #sprite.frames
|
|
19
|
+
}))
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
-- Returns information about the current frame.
|
|
2
|
+
-- Params:
|
|
3
|
+
-- none
|
|
4
|
+
|
|
5
|
+
local sprite = app.activeSprite
|
|
6
|
+
|
|
7
|
+
if not sprite then
|
|
8
|
+
print("ERROR: No active sprite")
|
|
9
|
+
return
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
local result = {
|
|
13
|
+
currentFrame = app.activeFrame.frameNumber,
|
|
14
|
+
frames = {}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
for i, frame in ipairs(sprite.frames) do
|
|
18
|
+
table.insert(result.frames, {
|
|
19
|
+
index = i,
|
|
20
|
+
duration = frame.duration
|
|
21
|
+
})
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
print(json.encode(result))
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
-- Returns true if the layer exists in the active sprite.
|
|
2
|
+
-- Params:
|
|
3
|
+
-- layerName : string
|
|
4
|
+
|
|
5
|
+
local p = app.params
|
|
6
|
+
local sprite = app.activeSprite
|
|
7
|
+
|
|
8
|
+
if not sprite then
|
|
9
|
+
print("ERROR: No active sprite")
|
|
10
|
+
return
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if not p or not p.layerName then
|
|
14
|
+
print("ERROR: layerName is required")
|
|
15
|
+
return
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
local function getIsLayerExists(layers)
|
|
19
|
+
for _, layer in ipairs(layers) do
|
|
20
|
+
if layer.name == p.layerName then
|
|
21
|
+
print(true)
|
|
22
|
+
return
|
|
23
|
+
end
|
|
24
|
+
if layer.isGroup and getIsLayerExists(layer.layers) then
|
|
25
|
+
print(true)
|
|
26
|
+
return
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
print(false)
|
|
30
|
+
return
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
print(getIsLayerExists(sprite.layers))
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-- Returns true if the tag exists in the active sprite.
|
|
2
|
+
-- Params:
|
|
3
|
+
-- tagName : string
|
|
4
|
+
|
|
5
|
+
local p = app.params
|
|
6
|
+
local sprite = app.activeSprite
|
|
7
|
+
|
|
8
|
+
if not sprite then
|
|
9
|
+
print("ERROR: No active sprite")
|
|
10
|
+
return
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if not p or not p.tagName then
|
|
14
|
+
print("ERROR: tagName is required")
|
|
15
|
+
return
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
for _, tag in ipairs(sprite.tags) do
|
|
19
|
+
if tag.name == p.tagName then
|
|
20
|
+
print(true)
|
|
21
|
+
return
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
print(false)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
-- Returns a list of all layers in the active sprite.
|
|
2
|
+
-- Params:
|
|
3
|
+
-- none
|
|
4
|
+
|
|
5
|
+
local sprite = app.activeSprite
|
|
6
|
+
|
|
7
|
+
if not sprite then
|
|
8
|
+
print("ERROR: No active sprite")
|
|
9
|
+
return
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
local layers = {}
|
|
13
|
+
|
|
14
|
+
local function listLayers(layersList)
|
|
15
|
+
for _, layer in ipairs(layersList) do
|
|
16
|
+
table.insert(layers, {
|
|
17
|
+
name = layer.name,
|
|
18
|
+
index = layer.stackIndex,
|
|
19
|
+
isGroup = layer.isGroup,
|
|
20
|
+
visible = layer.isVisible,
|
|
21
|
+
editable = layer.isEditable
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
if layer.isGroup then
|
|
25
|
+
listLayers(layer.layers)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
listLayers(sprite.layers)
|
|
31
|
+
print(json.encode(layers))
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
-- Returns information about the palette of the active sprite.
|
|
2
|
+
-- Params:
|
|
3
|
+
-- none
|
|
4
|
+
|
|
5
|
+
local sprite = app.activeSprite
|
|
6
|
+
|
|
7
|
+
if not sprite then
|
|
8
|
+
print("ERROR: No active sprite")
|
|
9
|
+
return
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
local palette = sprite.palettes[1]
|
|
13
|
+
|
|
14
|
+
if not palette then
|
|
15
|
+
print("ERROR: No palette found")
|
|
16
|
+
return
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
local colors = {}
|
|
20
|
+
|
|
21
|
+
for i = 0, #colors - 1 do
|
|
22
|
+
local c = palette:getColor(i)
|
|
23
|
+
table.insert(colors, {
|
|
24
|
+
r = c.red,
|
|
25
|
+
g = c.green,
|
|
26
|
+
b = c.blue,
|
|
27
|
+
a = c.alpha
|
|
28
|
+
})
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
print(json.encode({
|
|
32
|
+
size = #colors,
|
|
33
|
+
colors = colors
|
|
34
|
+
}))
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
-- Returns the bounds of the selection in the active sprite.
|
|
2
|
+
-- Params:
|
|
3
|
+
-- none
|
|
4
|
+
|
|
5
|
+
local sprite = app.activeSprite
|
|
6
|
+
|
|
7
|
+
if not sprite then
|
|
8
|
+
print("ERROR: No active sprite")
|
|
9
|
+
return
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
local sel = sprite.selection
|
|
13
|
+
|
|
14
|
+
if sel.isEmpty then
|
|
15
|
+
print("ERROR: No selection")
|
|
16
|
+
return
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
print(json.encode({
|
|
20
|
+
x = sel.bounds.x,
|
|
21
|
+
y = sel.bounds.y,
|
|
22
|
+
width = sel.bounds.width,
|
|
23
|
+
height = sel.bounds.height
|
|
24
|
+
}))
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-- Returns a list of all tags in the active sprite.
|
|
2
|
+
-- Params:
|
|
3
|
+
-- none
|
|
4
|
+
|
|
5
|
+
local sprite = app.activeSprite
|
|
6
|
+
|
|
7
|
+
if not sprite then
|
|
8
|
+
print("ERROR: No active sprite")
|
|
9
|
+
return
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
local tags = {}
|
|
13
|
+
|
|
14
|
+
for _, tag in ipairs(sprite.tags) do
|
|
15
|
+
table.insert(tags, {
|
|
16
|
+
name = tag.name,
|
|
17
|
+
from = tag.fromFrame.frameNumber,
|
|
18
|
+
to = tag.toFrame.frameNumber,
|
|
19
|
+
direction = tag.aniDir == AniDir.FORWARD and "forward"
|
|
20
|
+
or tag.aniDir == AniDir.REVERSE and "reverse"
|
|
21
|
+
or "pingpong"
|
|
22
|
+
})
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
print(json.encode(tags))
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
-- Merges all visible layers into a single layer and saves the result.
|
|
2
|
+
-- Params:
|
|
3
|
+
-- saveOutput : string
|
|
4
|
+
|
|
5
|
+
local p = app.params
|
|
6
|
+
|
|
7
|
+
if not p or not p.saveOutput then
|
|
8
|
+
print("ERROR: saveOutput is required")
|
|
9
|
+
return
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
local sprite = app.activeSprite
|
|
13
|
+
|
|
14
|
+
if not sprite then
|
|
15
|
+
print("ERROR: No active sprite")
|
|
16
|
+
return
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
app.command.FlattenLayers()
|
|
20
|
+
|
|
21
|
+
sprite:saveAs(p.saveOutput)
|
|
22
|
+
|
|
23
|
+
sprite:close()
|
|
24
|
+
print("merge_visible_layers script executed successfully")
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
-- Normalize all frame durations to a single targetDuration (seconds).
|
|
2
|
+
-- Params:
|
|
3
|
+
-- inputFile : string (already opened in Aseprite CLI or app.activeSprite)
|
|
4
|
+
-- saveOutput : string
|
|
5
|
+
-- targetDuration : string/number (seconds)
|
|
6
|
+
|
|
7
|
+
local p = app.params
|
|
8
|
+
|
|
9
|
+
local targetStr = p.targetDuration
|
|
10
|
+
if not targetStr then
|
|
11
|
+
print("ERROR: targetDuration is required")
|
|
12
|
+
return
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
local target = tonumber(targetStr)
|
|
16
|
+
if not target or target <= 0 then
|
|
17
|
+
print("ERROR: targetDuration must be positive number, got: " .. tostring(targetStr))
|
|
18
|
+
return
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
local spr = app.activeSprite
|
|
22
|
+
if not spr then
|
|
23
|
+
print("ERROR: No active sprite")
|
|
24
|
+
return
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
for i, frame in ipairs(spr.frames) do
|
|
28
|
+
frame.duration = target
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
local saveOutput = p.saveOutput or p.inputFile
|
|
32
|
+
if saveOutput and saveOutput ~= "" then
|
|
33
|
+
app.command.SaveFileAs{
|
|
34
|
+
filename = saveOutput
|
|
35
|
+
}
|
|
36
|
+
else
|
|
37
|
+
app.command.SaveFile()
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
print("normalize_animation_speed script executed successfully")
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
-- Recolors the palette based on a mapping of from->to colors.
|
|
2
|
+
-- Params:
|
|
3
|
+
-- saveOutput : string
|
|
4
|
+
-- mapping : string ("RRGGBB:RRGGBB;RRGGBB:RRGGBB;...")
|
|
5
|
+
|
|
6
|
+
local p = app.params
|
|
7
|
+
|
|
8
|
+
if not p or not p.saveOutput or not p.mapping then
|
|
9
|
+
print("ERROR: saveOutput and mapping are required")
|
|
10
|
+
return
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
local sprite = app.activeSprite
|
|
14
|
+
if not sprite then
|
|
15
|
+
print("ERROR: No active sprite")
|
|
16
|
+
return
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
local function parseColor(hex)
|
|
20
|
+
hex = hex:lower()
|
|
21
|
+
if #hex ~= 6 then return nil end
|
|
22
|
+
local r = tonumber(hex:sub(1, 2), 16)
|
|
23
|
+
local g = tonumber(hex:sub(3, 4), 16)
|
|
24
|
+
local b = tonumber(hex:sub(5, 6), 16)
|
|
25
|
+
return r,g,b
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
local rules = {}
|
|
29
|
+
for pair in string.gmatch(p.mapping, "([^;]+)") do
|
|
30
|
+
local fromHex, toHex = pair:match("([^:]+):([^:]+)")
|
|
31
|
+
if fromHex and toHex then
|
|
32
|
+
table.insert(rules, {
|
|
33
|
+
from = fromHex:lower(),
|
|
34
|
+
to = toHex:lower()
|
|
35
|
+
})
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
if #rules == 0 then
|
|
40
|
+
print("ERROR: No valid mapping rules found")
|
|
41
|
+
return
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
local function recolorIndexed()
|
|
46
|
+
print("Indexed mode detected: Using palette recolor")
|
|
47
|
+
|
|
48
|
+
local basePal = sprite.palettes[1] or sprite.palette
|
|
49
|
+
if not basePal then
|
|
50
|
+
print("ERROR: No palette found")
|
|
51
|
+
return false
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
for i = 0, #basePal - 1 do
|
|
55
|
+
local c = basePal:getColor(i)
|
|
56
|
+
local cr = string.format("%02x%02x%02x", c.red, c.green, c.blue)
|
|
57
|
+
|
|
58
|
+
for _, rule in ipairs(rules) do
|
|
59
|
+
if cr == rule.from then
|
|
60
|
+
local r,g,b = parseColor(rule.to)
|
|
61
|
+
if r and g and b then
|
|
62
|
+
basePal:setColor(i,
|
|
63
|
+
Color{ r=r, g=g, b=b, a=c.alpha }
|
|
64
|
+
)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
return true
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
local function recolorRGBA()
|
|
75
|
+
print("RGBA mode detected: Using pixel replacement")
|
|
76
|
+
|
|
77
|
+
app.transaction(function()
|
|
78
|
+
for _, cel in ipairs(sprite.cels) do
|
|
79
|
+
local img = cel.image
|
|
80
|
+
local w = img.width
|
|
81
|
+
local h = img.height
|
|
82
|
+
|
|
83
|
+
for y = 0, h - 1 do
|
|
84
|
+
for x = 0, w - 1 do
|
|
85
|
+
local px = img:getPixel(x, y)
|
|
86
|
+
|
|
87
|
+
local r = app.pixelColor.rgbaR(px)
|
|
88
|
+
local g = app.pixelColor.rgbaG(px)
|
|
89
|
+
local b = app.pixelColor.rgbaB(px)
|
|
90
|
+
local a = app.pixelColor.rgbaA(px)
|
|
91
|
+
|
|
92
|
+
local key = string.format("%02x%02x%02x", r,g,b)
|
|
93
|
+
|
|
94
|
+
for _, rule in ipairs(rules) do
|
|
95
|
+
if key == rule.from then
|
|
96
|
+
local nr,ng,nb = parseColor(rule.to)
|
|
97
|
+
if nr and ng and nb then
|
|
98
|
+
img:putPixel(x, y,
|
|
99
|
+
app.pixelColor.rgba(nr,ng,nb,a))
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end)
|
|
107
|
+
|
|
108
|
+
return true
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
local ok = false
|
|
113
|
+
|
|
114
|
+
if sprite.colorMode == ColorMode.INDEXED then
|
|
115
|
+
ok = recolorIndexed()
|
|
116
|
+
else
|
|
117
|
+
print("WARNING: Sprite is NOT Indexed Color.")
|
|
118
|
+
print("Fallback to RGBA pixel replacement recoloring.")
|
|
119
|
+
ok = recolorRGBA()
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
if not ok then
|
|
123
|
+
print("ERROR: recoloring failed")
|
|
124
|
+
return
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
if p.saveOutput and p.saveOutput ~= "" then
|
|
128
|
+
sprite:saveAs(p.saveOutput)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
print("recolor_palette script executed successfully")
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
-- Removes a layer by name and saves to a new file (or overwrites).
|
|
2
|
+
-- Params (app.params):
|
|
3
|
+
-- layerName : string
|
|
4
|
+
-- saveOutput : string (optional, default = inputFile)
|
|
5
|
+
|
|
6
|
+
local p = app.params
|
|
7
|
+
|
|
8
|
+
if not p or not p.layerName or not p.saveOutput then
|
|
9
|
+
print("ERROR: layerName and saveOutput are required")
|
|
10
|
+
return
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
local sprite = app.activeSprite
|
|
14
|
+
if not sprite then
|
|
15
|
+
print("ERROR: No active sprite")
|
|
16
|
+
return
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
local found = false
|
|
20
|
+
|
|
21
|
+
for i, layer in ipairs(sprite.layers) do
|
|
22
|
+
if layer.name == p.layerName then
|
|
23
|
+
app.activeLayer = layer
|
|
24
|
+
app.command.RemoveLayer()
|
|
25
|
+
found = true
|
|
26
|
+
break
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
if not found then
|
|
31
|
+
print("WARN: Layer not found: " .. p.layerName)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if p.saveOutput and p.saveOutput ~= "" then
|
|
35
|
+
sprite:saveAs(p.saveOutput)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
print("remove_layer_by_name script executed successfully")
|
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iborymagic/aseprite-mcp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"description": "MCP server for using Aseprite API",
|
|
5
|
-
"main": "index.js",
|
|
6
5
|
"type": "module",
|
|
7
6
|
"bin": {
|
|
8
7
|
"aseprite-mcp": "./build/index.js"
|
|
@@ -10,8 +9,12 @@
|
|
|
10
9
|
"files": [
|
|
11
10
|
"build"
|
|
12
11
|
],
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
13
15
|
"scripts": {
|
|
14
|
-
"build": "tsc",
|
|
16
|
+
"build": "tsc && npm run copy:lua",
|
|
17
|
+
"copy:lua": "cp -R src/lua/templates build/lua/templates",
|
|
15
18
|
"start": "node build/index.js",
|
|
16
19
|
"dev": "npm run build && npm run start",
|
|
17
20
|
"test": "vitest"
|