Skip to content

Commit 3b1a5af

Browse files
committed
Updated for AJ 1.7.3
1 parent 367a1d3 commit 3b1a5af

File tree

1 file changed

+119
-138
lines changed

1 file changed

+119
-138
lines changed
Lines changed: 119 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1,192 +1,173 @@
11
import sys
22
import nbtlib
33
import os
4-
import re
5-
6-
OFFSETS = (
7-
("head", 0.0), ("right_arm", -1024.0), ("left_arm", -2048.0),
8-
("torso", -3072.0), ("right_leg", -4096.0), ("left_leg", -5120.0)
9-
)
10-
11-
SPLIT_OFFSETS = (
12-
("head", 0.0),("right_arm", -1024.0), ("right_forearm", -6144.0), ("left_arm", -2048.0), ("left_forearm", -7168.0),
13-
("torso", -3072.0), ("waist", -8192.0), ("right_leg", -4096.0), ("lower_right_leg", -9216.0) ,("left_leg", -5120.0), ("lower_left_leg", -10240.0)
14-
)
15-
16-
def parse_arguments():
17-
"""Parse command-line arguments."""
18-
nArgs = len(sys.argv)
19-
if nArgs < 2:
20-
print("Usage: aj-convert.py [project] [optional:flags]")
21-
print("Available flags:")
22-
print("\t-pn=[playerName]\tPlayer skin to use. Default '' (no skin), must be set later in game")
23-
print("\t-split\tEnables split mode where the player model has extra joints (player_split.ajblueprint)")
4+
5+
# Offset mappings for different player model modes
6+
DEFAULT_OFFSETS = {
7+
"head": 0.0, "right_arm": -1024.0, "left_arm": -2048.0,
8+
"torso": -3072.0, "right_leg": -4096.0, "left_leg": -5120.0
9+
}
10+
11+
SPLIT_OFFSETS = {
12+
"head": 0.0, "right_arm": -1024.0, "right_forearm": -6144.0,
13+
"left_arm": -2048.0, "left_forearm": -7168.0, "torso": -3072.0,
14+
"waist": -8192.0, "right_leg": -4096.0, "lower_right_leg": -9216.0,
15+
"left_leg": -5120.0, "lower_left_leg": -10240.0
16+
}
17+
18+
def parse_cli_arguments():
19+
"""Parse and validate command-line arguments."""
20+
if len(sys.argv) < 2:
21+
print_usage()
2422
sys.exit(1)
2523

2624
project = sys.argv[1]
27-
playerName = ""
28-
offsets = OFFSETS
29-
30-
if nArgs > 2:
31-
for arg in sys.argv[2:]:
32-
if arg.startswith("-pn="):
33-
playerName = arg[4:]
34-
if arg.startswith("-split"):
35-
offsets = SPLIT_OFFSETS
36-
37-
return project, playerName, offsets
38-
39-
def read_and_modify_summon_function(summonPath, project, offsets, playerName):
40-
"""Read and modify the summon.mcfunction file."""
41-
summonResult = ""
42-
25+
player_name = ""
26+
offsets = DEFAULT_OFFSETS
27+
28+
for arg in sys.argv[2:]:
29+
if arg.startswith("-pn="):
30+
player_name = arg[4:]
31+
elif arg == "-split":
32+
offsets = SPLIT_OFFSETS
33+
34+
return project, player_name, offsets
35+
36+
def print_usage():
37+
"""Display usage instructions."""
38+
print("Usage: aj-convert.py [project] [optional:flags]")
39+
print("Available flags:")
40+
print("\t-pn=[playerName]\tSpecify the player skin (default: none)")
41+
print("\t-split\tEnable split mode with extra joints")
42+
43+
def modify_summon_file(filepath, project, offsets, player_name):
44+
"""Modify the summon.mcfunction file with new offsets and player skin."""
4345
try:
44-
with open(summonPath, "r") as f:
45-
for _ in range(3):
46-
summonResult += f.readline()
46+
with open(filepath, "r") as file:
47+
summon_content = [file.readline() for _ in range(3)]
48+
summon_data = file.readline()
4749

48-
temp = f.readline()
49-
50-
if temp[-4] == ',':
51-
temp = temp[:-4] + temp[-3:] # Remove malformed last comma
50+
if summon_data[-4] == ",":
51+
summon_data = summon_data[:-4] + summon_data[-3:]
5252

53-
nbtStart = temp.index("~ ~ ~ ") + len("~ ~ ~ ")
54-
summonResult += temp[:nbtStart]
55-
nbt_data = temp[nbtStart:]
53+
nbt_start = summon_data.index("~ ~ ~ ") + len("~ ~ ~ ")
54+
summon_content.append(summon_data[:nbt_start])
55+
nbt_data = summon_data[nbt_start:]
5656

57-
nbtRoot = nbtlib.parse_nbt(nbt_data)
58-
modify_nbt_passengers(nbtRoot, project, offsets, playerName)
57+
nbt_root = nbtlib.parse_nbt(nbt_data)
58+
update_nbt_passengers(nbt_root, project, offsets, player_name)
5959

60-
summonResult += nbtlib.serialize_tag(nbtRoot, compact=True) + "\n"
61-
summonResult += f.readline()
60+
summon_content.append(nbtlib.serialize_tag(nbt_root, compact=True) + "\n")
61+
summon_content.append(file.readline())
6262

63-
with open(summonPath, "w") as f:
64-
f.write(summonResult)
63+
with open(filepath, "w") as file:
64+
file.writelines(summon_content)
6565

66-
print(f"Successfully modified {summonPath}")
66+
print(f"Successfully updated: {filepath}")
6767

6868
except Exception as e:
69-
print(f"Error processing {summonPath}: {e}")
69+
print(f"Error updating {filepath}: {e}")
7070
sys.exit(1)
7171

72-
def modify_nbt_passengers(nbtRoot, project, offsets, playerName):
73-
"""Modify NBT data for passengers."""
74-
for passenger in nbtRoot["Passengers"][1:]: # Skip First Marker
75-
for offsetPair in offsets:
76-
tag = f"aj.{project}.bone.{offsetPair[0]}"
72+
def update_nbt_passengers(nbt_root, project, offsets, player_name):
73+
"""Apply offsets and player skin to NBT passenger data."""
74+
for passenger in nbt_root["Passengers"][1:]:
75+
for bone_name, offset in offsets.items():
76+
tag = f"aj.{project}.bone.{bone_name}"
7777
if tag in passenger["Tags"]:
78-
passenger["transformation"]["translation"][1] += offsetPair[1]
78+
passenger["transformation"]["translation"][1] += offset
7979
passenger["item_display"] = nbtlib.tag.String("thirdperson_righthand")
80-
81-
if playerName:
82-
passenger["item"]["id"] = nbtlib.tag.String("minecraft:player_head")
83-
passenger["item"]["components"]["profile"] = nbtlib.tag.Compound({"name": nbtlib.tag.String(playerName)})
84-
else:
85-
passenger["item"]["id"] = nbtlib.tag.String("minecraft:air")
86-
87-
def process_pose_files(paths, project, offsets):
88-
"""Process set_default_pose.mcfunction and apply_default_pose.mcfunction files."""
89-
for path in paths:
90-
try:
91-
with open(path, "r") as f:
92-
lines = f.readlines()
80+
passenger["item"]["id"] = nbtlib.tag.String("minecraft:player_head" if player_name else "minecraft:air")
81+
if player_name:
82+
passenger["item"]["components"]["profile"] = nbtlib.tag.Compound({"name": nbtlib.tag.String(player_name)})
9383

94-
modifiedLines = []
95-
for line in lines:
96-
if "merge entity @s" in line:
97-
modifiedLines.append(modify_merge_entity_line(line, project, offsets))
98-
else:
99-
modifiedLines.append(line)
84+
def update_pose_files(filepaths, project, offsets):
85+
"""Update set_default_pose.mcfunction and apply_default_pose.mcfunction files."""
86+
for path in filepaths:
87+
try:
88+
with open(path, "r") as file:
89+
lines = [modify_pose_line(line, project, offsets) for line in file]
10090

101-
with open(path, "w") as f:
102-
f.writelines(modifiedLines)
91+
with open(path, "w") as file:
92+
file.writelines(lines)
10393

104-
print(f"Successfully modified {path}")
94+
print(f"Updated pose file: {path}")
10595

10696
except Exception as e:
10797
print(f"Error processing {path}: {e}")
10898
sys.exit(1)
10999

110-
def modify_merge_entity_line(line, project, offsets):
111-
"""Modify a merge entity line with the appropriate offsets."""
112-
for offsetPair in offsets:
113-
if f"[tag=aj.{project}.bone.{offsetPair[0]}]" in line:
114-
nbtStart = line.index("merge entity @s ") + len("merge entity @s ")
115-
tmpLine = line[:nbtStart]
116-
nbtRoot = nbtlib.parse_nbt(line[nbtStart:])
117-
nbtRoot["transformation"][7] += offsetPair[1]
118-
return tmpLine + nbtlib.serialize_tag(nbtRoot, compact=True) + "\n"
100+
def modify_pose_line(line, project, offsets):
101+
"""Modify a line with the appropriate transformation offset."""
102+
for bone_name, offset in offsets.items():
103+
tag = f"[tag=aj.{project}.bone.{bone_name}]"
104+
if tag in line:
105+
nbt_start = line.index("merge entity @s ") + len("merge entity @s ")
106+
tmp_line = line[:nbt_start]
107+
nbt_root = nbtlib.parse_nbt(line[nbt_start:])
108+
nbt_root["transformation"][7] += offset
109+
return tmp_line + nbtlib.serialize_tag(nbt_root, compact=True) + "\n"
119110
return line
120111

121-
def modify_animation_frames(rootpath, project, offsets):
122-
"""Modify all animation frames in the specified project."""
112+
def process_animation_frames(rootpath, offsets):
113+
"""Modify all animation frames within the specified root directory."""
123114
try:
124-
subfolders = [entry for entry in os.listdir(rootpath) if os.path.isdir(os.path.join(rootpath, entry))]
125-
126-
for animation in subfolders:
115+
for animation in os.listdir(rootpath):
127116
frames_path = os.path.join(rootpath, animation, "zzz", "frames")
128-
frames = [entry for entry in os.listdir(frames_path) if os.path.isfile(os.path.join(frames_path, entry))]
129-
130-
i = 0
131-
for frame in frames:
132-
i+=1
133-
sys.stdout.write(f"\rEditing {animation} frames: [{i}/{len(frames)}]")
134-
framepath = os.path.join(frames_path, frame)
135-
modify_frame_file(framepath, offsets)
117+
if not os.path.isdir(frames_path):
118+
continue
119+
120+
frames = os.listdir(frames_path)
121+
for index, frame in enumerate(frames, start=1):
122+
frame_path = os.path.join(frames_path, frame)
123+
modify_frame_file(frame_path, offsets)
124+
sys.stdout.write(f"\rProcessing {animation} frames: [{index}/{len(frames)}]")
136125
print()
137126

138127
except Exception as e:
139-
print(f"Error processing animations: {e}")
128+
print(f"Error processing animation frames: {e}")
140129
sys.exit(1)
141130

142-
def modify_frame_file(framepath, offsets):
143-
"""Modify a single frame file with the appropriate offsets."""
131+
def modify_frame_file(filepath, offsets):
132+
"""Modify an individual frame file by applying offsets."""
144133
try:
145-
with open(framepath, "r") as f:
146-
lines = f.readlines()
147-
148-
modifiedLines = []
149-
for line in lines:
150-
if ") " in line:
151-
modifiedLines.append(modify_frame_line(line, offsets))
152-
else:
153-
modifiedLines.append(line)
134+
with open(filepath, "r") as file:
135+
lines = [modify_frame_line(line, offsets) for line in file]
154136

155-
with open(framepath, "w") as f:
156-
f.writelines(modifiedLines)
137+
with open(filepath, "w") as file:
138+
file.writelines(lines)
157139

158140
except Exception as e:
159-
print(f"Error processing frame {framepath}: {e}")
141+
print(f"Error processing frame {filepath}: {e}")
160142

161143
def modify_frame_line(line, offsets):
162-
"""Modify a line in a frame file with the appropriate offsets."""
163-
for offsetPair in offsets:
164-
# Construct the exact pattern to match
165-
target = f"$data merge entity $(bone_{offsetPair[0]})"
144+
"""Modify a frame line by adjusting transformation values."""
145+
for bone_name, offset in offsets.items():
146+
target = f"$data merge entity $(bone_{bone_name})"
166147
if target in line:
167-
nbtStart = line.index(") ") + len(") ")
168-
tmpLine = line[:nbtStart]
169-
nbtRoot = nbtlib.parse_nbt(line[nbtStart:])
170-
nbtRoot["transformation"][7] += offsetPair[1]
171-
return tmpLine + nbtlib.serialize_tag(nbtRoot, compact=True) + "\n"
148+
nbt_start = line.index(") ") + len(") ")
149+
tmp_line = line[:nbt_start]
150+
nbt_root = nbtlib.parse_nbt(line[nbt_start:])
151+
nbt_root["transformation"][7] += offset
152+
return tmp_line + nbtlib.serialize_tag(nbt_root, compact=True) + "\n"
172153
return line
173154

174155
def main():
175-
project, playerName, offsets = parse_arguments()
156+
project, player_name, offsets = parse_cli_arguments()
176157

177-
print(f"Running aj-convert on project {project}")
158+
print(f"Starting aj-convert for project: {project}")
178159

179-
summonPath = os.path.join(".","animated_java", "data", "animated_java", "function", project, "summon.mcfunction")
180-
read_and_modify_summon_function(summonPath, project, offsets, playerName)
160+
summon_filepath = os.path.join(".", "data", "animated_java", "function", project, "summon.mcfunction")
161+
modify_summon_file(summon_filepath, project, offsets, player_name)
181162

182-
mcfunction_paths = [
183-
os.path.join(".","animated_java", "data", "animated_java", "function", project, "set_default_pose.mcfunction"),
184-
os.path.join(".","animated_java", "data", "animated_java", "function", project, "apply_default_pose.mcfunction")
163+
pose_filepaths = [
164+
os.path.join(".", "data", "animated_java", "function", project, "set_default_pose.mcfunction"),
165+
os.path.join(".", "data", "animated_java", "function", project, "apply_default_pose.mcfunction")
185166
]
186-
process_pose_files(mcfunction_paths, project, offsets)
167+
update_pose_files(pose_filepaths, project, offsets)
187168

188-
animations_rootpath = os.path.join(".","animated_java", "data", "animated_java", "function", project, "animations")
189-
modify_animation_frames(animations_rootpath, project, offsets)
169+
animation_rootpath = os.path.join(".", "data", "animated_java", "function", project, "animations")
170+
process_animation_frames(animation_rootpath, offsets)
190171

191172
if __name__ == "__main__":
192173
main()

0 commit comments

Comments
 (0)