|
2 | 2 | from struct import pack, unpack
|
3 | 3 | import sys
|
4 | 4 | import os
|
| 5 | +import json |
5 | 6 |
|
6 | 7 | @dataclass
|
7 | 8 | class Action:
|
@@ -44,6 +45,17 @@ def parse_zbot(data: bytes) -> Replay:
|
44 | 45 | actions.append(Action(x, hold == 0x31, player_1 != 0x31))
|
45 | 46 | return Replay(fps, actions)
|
46 | 47 |
|
| 48 | +def parse_ybot(data: bytes) -> Replay: |
| 49 | + data = json.loads(data) |
| 50 | + levels = list(data.keys()) |
| 51 | + level = input(f'Choose a level {levels}: ') |
| 52 | + macro = data[level] |
| 53 | + fps = 1 / macro['delta_override'] |
| 54 | + actions = [] |
| 55 | + for inst in macro['instructions']: |
| 56 | + actions.append(Action(inst['x'], inst['press'], inst['p2'])) |
| 57 | + return Replay(fps, actions) |
| 58 | + |
47 | 59 | def dump_replaybot(replay: Replay) -> bytearray:
|
48 | 60 | data = bytearray()
|
49 | 61 | data.extend(pack('f', replay.fps))
|
@@ -77,44 +89,50 @@ def dump_txt(replay: Replay) -> str:
|
77 | 89 | final += f'{action.x} {int(action.hold)} {int(action.player_2)}\n'
|
78 | 90 | return final[:-1]
|
79 | 91 |
|
80 |
| -if len(sys.argv) != 4: |
81 |
| - print('''\ |
82 |
| -Usage: python converter.py (from) format (to) |
83 |
| -format can be either zbot, replaybot or txt |
| 92 | +FORMATS = {'txt', 'replaybot', 'zbot', 'ybot'} |
| 93 | + |
| 94 | +if len(sys.argv) != 5: |
| 95 | + print(f'''\ |
| 96 | +Usage: python converter.py format (from) format (to) |
| 97 | +format can be either {", ".join(FORMATS)} |
84 | 98 | Example:
|
85 | 99 | Converts from zBot to ReplayBot
|
86 |
| - python converter.py "Sonic Wave.zbot" replaybot "Sonic Wave.replay" |
| 100 | + python converter.py zbot "Sonic Wave.zbot" replaybot "Sonic Wave.replay" |
87 | 101 |
|
88 | 102 | Converts from zBot to txt
|
89 |
| - python converter.py "Tartarus.zbot" txt "tartarus.txt" |
| 103 | + python converter.py zbot "Tartarus.zbot" txt "tartarus.txt" |
90 | 104 | ''')
|
91 | 105 | exit(1)
|
92 | 106 |
|
93 |
| -if os.path.exists(sys.argv[3]): |
94 |
| - print(f'{sys.argv[3]} already exists') |
| 107 | +if os.path.exists(sys.argv[4]): |
| 108 | + print(f'{sys.argv[4]} already exists') |
95 | 109 | exit(1)
|
96 | 110 |
|
97 |
| -FORMATS = {'txt', 'replaybot', 'zbot'} |
| 111 | +from_format = sys.argv[1] |
98 | 112 |
|
99 |
| -from_format = os.path.splitext(sys.argv[1])[1][1:] |
| 113 | +to = sys.argv[3] |
100 | 114 |
|
101 |
| -to = sys.argv[2] |
102 |
| - |
103 |
| -if to not in FORMATS: |
| 115 | +if to not in FORMATS or from_format not in FORMATS: |
104 | 116 | print(f'format can only be {FORMATS}')
|
105 | 117 | exit(1)
|
106 | 118 |
|
107 |
| -with open(sys.argv[1], 'rb') as file: |
| 119 | +if to == 'ybot': |
| 120 | + print('cant convert to ybot (yet)') |
| 121 | + exit(1) |
| 122 | + |
| 123 | +with open(sys.argv[2], 'rb') as file: |
108 | 124 | data = file.read()
|
109 | 125 |
|
110 | 126 | if from_format == 'zbot':
|
111 | 127 | replay = parse_zbot(data)
|
112 | 128 | elif from_format == 'txt':
|
113 | 129 | replay = parse_txt(data)
|
114 |
| -else: |
| 130 | +elif from_format == 'ybot': |
| 131 | + replay = parse_ybot(data) |
| 132 | +elif from_format == 'replaybot': |
115 | 133 | replay = parse_replaybot(data)
|
116 | 134 |
|
117 |
| -with open(sys.argv[3], 'wb') as file: |
| 135 | +with open(sys.argv[4], 'wb') as file: |
118 | 136 | if to == 'zbot':
|
119 | 137 | file.write(dump_zbot(replay))
|
120 | 138 | elif to == 'txt':
|
|
0 commit comments