-
Notifications
You must be signed in to change notification settings - Fork 24
/
AddOutputIndex.js
152 lines (129 loc) · 4.96 KB
/
AddOutputIndex.js
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
/* Add Output Index script by eishiya, last updated 15 Mar 2024
Requires Tiled 1.10.2+
As of Tiled 1.10.3, output layers without an index always get output.
Before, such layers would simply count as another index to choose at random.
This causes a potential change in behaviour for older Automapping rules.
This script adds an action to the Map menu that updates old rules
to work the same as they did before.
For any rules map it finds that has output layers with named indices,
any output layers *without* named indices get a named index.
This script will attempt to fix commented-out layer names too,
as long as they're otherwise valid, e.g.
"//output_Blah" will get fixed, "//TODO: output_Blah" will not.
The replacement index will be "0". If such an index already exists
in the map, it will be "00", and so on.
Any maps that are modified by the script will be left open and not saved.
This makes it easier for you to verify the changes. You can Save All if you
don't want to check and save each one manually.
If you have a Project loaded, the project's directories will be scanned.
Otherwise, you'll be prompted to select a directory to scan.
If you have many maps, this script can take a while to run!
You should only need to run this script once per pre-1.10.3 Project.
You can uninstall it when you're done, or comment out the last 3 lines so
it doesn't clutter your Map menu, in which case you can still run the script
via Search Actions.
*/
let addOutputIndex = tiled.registerAction("AddOutputIndex", function(/* action */) {
function fixIndex(map) {
let newIndexCharacter = "0";
let newIndex = newIndexCharacter;
let layersToRename = [];
let hasNamedIndices = false;
function checkLayer(layer) {
if(!layer) return;
if(layer.isGroupLayer || layer.isTileMap) {
//process over its child layers recursively:
for(let gi = 0; gi < layer.layerCount; ++gi) {
checkLayer(layer.layerAt(gi));
}
} else { //regular layer that may be an output layer
let layerName = layer.name;
//to fix commented-out layers, strip the comment bit:
layerName.replace(/^(\/\/|#)\s*/, '');
if(layerName.indexOf("output_") == 0) //output with unnamed index
layersToRename.push(layer);
else {
//the name has output but not output_, it must have a named output index
if(layerName.indexOf("output") == 0)
hasNamedIndices = true;
//If our new index would conflict with an existing index, change it:
while(layerName.indexOf("output"+newIndex+"_") == 0)
newIndex += newIndexCharacter;
}
}
}
checkLayer(map);
if(hasNamedIndices && layersToRename.length > 0) {
map.macro("Add Output Index", function() {
for(let layer of layersToRename)
layer.name = layer.name.replace("output_", "output"+newIndex+"_");
tiled.log("Renamed "+layersToRename.length+" layer(s) in "+map.fileName);
});
return layersToRename.length;
}
return 0;
}
let maps = [];
//Helper function that returns a TileMap if it's already open
function getOpenMap(file) {
for(let asset of tiled.openAssets) {
if(asset.fileName == file && asset.isTileMap)
return asset;
}
return null;
}
//Recursively add all the maps in a folder to maps
let checkedFolders = {};
function collectMaps(folder) {
let canonicalPath = FileInfo.canonicalPath(folder);
if(checkedFolders[canonicalPath]) return;
checkedFolders[canonicalPath] = true;
//First, get all the files in this folder
let files = File.directoryEntries(folder, File.Files | File.Readable | File.NoDotAndDotDot);
for(let file of files) {
let path = folder+"/"+file;
let format = tiled.mapFormatForFile(path);
if(format) {
let map = getOpenMap(path);
if(map)
maps.push(map);
else
maps.push(path);
} //else there's no map format that can read this file, it's not a Tiled map, skip it.
}
//Then, look at any subfolders:
files = File.directoryEntries(folder, File.Dirs | File.Readable | File.NoDotAndDotDot);
for(let file of files) {
collectMaps(folder+"/"+file);
}
}
let folders;
if(tiled.project && tiled.projectFilePath.length > 0)
folders = tiled.project.folders;
else
folders = [tiled.promptDirectory(null, "Select a directory to scan")];
for(let folder of folders)
collectMaps(folder);
let previousAsset = tiled.activeAsset;
let totalLayersChanged = 0;
for(let map of maps) {
if(map.isTileMap) {
totalLayersChanged += fixIndex(map);
} else { //a path
map = tiled.open(map);
let layersChanged = fixIndex(map);
totalLayersChanged += layersChanged;
if(layersChanged == 0) //leave modified maps open for inspection
tiled.close(map);
}
}
if(totalLayersChanged == 0)
tiled.log("No maps were found to need output index modification. No changes made.");
if(previousAsset)
tiled.activeAsset = previousAsset;
});
addOutputIndex.text = "Add Output Indices";
//Add this action to the Map menu:
tiled.extendMenu("Map", [
{ action: "AddOutputIndex", before: "AutoMapWhileDrawing" }
]);