Skip to content

Commit 4f54a80

Browse files
committed
fix(aiv): fix invert y bug
1 parent e33d827 commit 4f54a80

File tree

7 files changed

+73
-42
lines changed

7 files changed

+73
-42
lines changed

aivjsons.zip

293 KB
Binary file not shown.

sourcehold/tool/argparsers/common.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
file_input_file_output = argparse.ArgumentParser(add_help=False)
44
file_input_file_output.add_argument("--input", help="input file", required=True)
5-
file_input_file_output.add_argument("--output", help="output file")
5+
file_input_file_output.add_argument("--output", help="output file", required=False)
66

77
multiple_file_input_folder_output = argparse.ArgumentParser(add_help=False)
88
multiple_file_input_folder_output.add_argument("--input", help="input files", nargs='+', required=True)
9-
multiple_file_input_folder_output.add_argument("--output", help="ouput folder")
9+
multiple_file_input_folder_output.add_argument("--output", help="output folder")
1010

1111
main_parser = argparse.ArgumentParser(prog="sourcehold")
1212
main_parser.add_argument("--debug", action="store_true", default=False, help="debug mode")

sourcehold/tool/argparsers/services.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@
77
convert_subparsers = convert_parser.add_subparsers(dest='type', required=True, title='type')
88

99
convert_aiv_parser = convert_subparsers.add_parser('aiv', parents=[file_input_file_output])
10-
convert_aiv_parser.add_argument('--extra', action='store_const', const=True, default=False, help='include properties that have not been parsed as "extra"')
10+
convert_aiv_parser.add_argument('--extra', action='store_true', default=False, help='include properties that have not been parsed as "extra"')
1111
convert_aiv_parser.add_argument('--from-format', required=False, default='')
1212
convert_aiv_parser.add_argument('--to-format', required=False, default='')
13+
convert_aiv_parser.add_argument('--verify', default='', required=False, help='specify file path to verify file with')
14+
convert_aiv_parser.add_argument('--from-invert-y', type=bool, default=False)
15+
convert_aiv_parser.add_argument('--from-invert-x', type=bool, default=False)
16+
convert_aiv_parser.add_argument('--to-invert-y', type=bool, default=True)
17+
convert_aiv_parser.add_argument('--to-invert-x', type=bool, default=False)
1318

1419
memory_parser = services_parser.add_parser('memory')
1520
memory_parser.add_argument('--game', choices=['SHC1.41-latin', "SHCE1.41-latin"], default="SHC1.41-latin")

sourcehold/tool/convert/aiv/__init__.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
import pathlib, sys
23

34
from sourcehold.tool.convert.aiv.exports import to_json
@@ -15,19 +16,17 @@ def convert_aiv(args):
1516
inp = args.input
1617
if inp != '-' and not pathlib.Path(inp).exists():
1718
raise Exception(f"file does not exist: {inp}")
18-
inp_invert_y = False
19+
inp_invert_y = args.from_invert_y
20+
inp_invert_x = args.from_invert_x
1921
inp_format = args.from_format
2022
if not inp_format:
2123
if inp.endswith(".aiv"):
2224
inp_format = 'aiv'
2325
elif inp.endswith(".json"):
2426
inp_format = "json"
25-
else:
26-
inp_format_tokens = inp_format.split(",")
27-
if 'inverty' in inp_format_tokens:
28-
inp_invert_y = True
29-
30-
out_invert_y = False
27+
28+
out_invert_y = args.to_invert_y
29+
out_invert_x = args.to_invert_x
3130
out_skip_keep = False
3231
out_format = args.to_format
3332
if not out_format:
@@ -39,6 +38,8 @@ def convert_aiv(args):
3938
out_format_tokens = out_format.split(",")
4039
if 'inverty' in out_format_tokens:
4140
out_invert_y = True
41+
if 'invertx' in out_format_tokens:
42+
out_invert_x = True
4243
if 'skipkeep' in out_format_tokens:
4344
out_skip_keep = True
4445
if args.output == None:
@@ -56,17 +57,25 @@ def convert_aiv(args):
5657

5758
if inp_format.startswith('aiv') and out_format.startswith("json"):
5859

59-
conv = to_json(path = inp, include_extra=args.extra, report=args.debug, invert_y=out_invert_y, skip_keep=out_skip_keep)
60+
conv = to_json(path = inp, include_extra=args.extra, report=args.debug, invert_y=out_invert_y, invert_x=out_invert_x, skip_keep=out_skip_keep)
61+
if args.verify:
62+
target = json.dumps(json.loads(pathlib.Path(args.verify).read_text()), indent=2)
63+
target_lines = target.split("\n")
64+
conv_lines = conv.split("\n")
65+
nlines = min(len(target_lines), len(conv_lines))
66+
for li in range(nlines):
67+
if target_lines[li] != conv_lines[li]:
68+
print(f"Lines differ:\nSource:\n{conv_lines[li]}\nTarget:\n{target_lines[li]}", file=sys.stderr)
6069
if args.output == "-":
6170
sys.stdout.write(conv)
6271
sys.stdout.flush()
6372
else:
6473
pathlib.Path(args.output).write_text(conv)
6574
elif inp_format.startswith('json') and out_format.startswith("aiv"):
6675
if inp == "-":
67-
conv = from_json(f = sys.stdin, report=args.debug, invert_y=inp_invert_y)
76+
conv = from_json(f = sys.stdin, report=args.debug, invert_y=inp_invert_y, invert_x=inp_invert_x)
6877
else:
69-
conv = from_json(path = inp, report=args.debug, invert_y=inp_invert_y)
78+
conv = from_json(path = inp, report=args.debug, invert_y=inp_invert_y, invert_x=inp_invert_x)
7079
conv.to_file(args.output)
7180
else:
7281
raise NotImplementedError(f"combination of from-format '{inp_format}' and to-format '{out_format}' not implemented")

sourcehold/tool/convert/aiv/exports.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,17 @@
1919
import json
2020

2121

22+
def translate_offset(offset, invert_x, invert_y):
23+
x = offset % AIV_WIDTH
24+
y = offset // AIV_HEIGHT
25+
if invert_x:
26+
x = (AIV_WIDTH - 1) - x
27+
if invert_y:
28+
y = (AIV_HEIGHT - 1) - y
29+
return (y * AIV_HEIGHT) + x
2230

2331

24-
def to_json(aiv=None, path: str='', f=None, include_extra=False, invert_y=True, skip_keep=False, report=False):
32+
def to_json(aiv=None, path: str='', f=None, include_extra=False, invert_y=False, invert_x=True, skip_keep=False, report=False):
2533
if not aiv and not path and not f:
2634
raise Exception()
2735
if aiv == None:
@@ -63,16 +71,16 @@ def to_json(aiv=None, path: str='', f=None, include_extra=False, invert_y=True,
6371
frames = [None] * step_count # + 1 is already stored in the aiv format
6472
miscItems = []
6573

74+
output["pauseDelayAmount"] = pauseDelayAmount
6675
output["frames"] = frames
6776
output["miscItems"] = miscItems
68-
output["pauseDelayAmount"] = pauseDelayAmount
6977

7078
processed = {}
7179

7280
buildings = 0
7381
offset = -1
74-
for i in x_range():
75-
for j in y_range(invert_y=invert_y):
82+
for i in y_range(invert_y=False):
83+
for j in x_range(invert_x=False):
7684
offset += 1
7785

7886
if offset in processed:
@@ -110,16 +118,17 @@ def to_json(aiv=None, path: str='', f=None, include_extra=False, invert_y=True,
110118
if frames[step] is None:
111119
buildings += 1
112120
shouldPause = step in pauses
113-
frames[step] = {'itemType': buildingType, 'tilePositionOfsets': [offset], 'shouldPause': shouldPause}
121+
offset_t = translate_offset(offset, invert_x, invert_y)
122+
frames[step] = {'itemType': buildingType, 'tilePositionOfsets': [offset_t], 'shouldPause': shouldPause}
114123

115124
if report:
116125
print(f"INFO: buildings: {buildings}")
117126

118127
nonbuildings = 0
119128

120129
offset = -1
121-
for i in x_range():
122-
for j in y_range(invert_y=invert_y):
130+
for i in y_range(invert_y=False):
131+
for j in x_range(invert_x=False):
123132
offset += 1
124133
if offset not in processed:
125134
# do all the special stuff
@@ -129,20 +138,24 @@ def to_json(aiv=None, path: str='', f=None, include_extra=False, invert_y=True,
129138
shouldPause = step in pauses
130139
if frames[step] is None:
131140
frames[step] = {'itemType': buildingType, 'tilePositionOfsets': [], 'shouldPause': shouldPause}
132-
frames[step]['tilePositionOfsets'].append(offset)
141+
offset_t = translate_offset(offset, invert_x, invert_y)
142+
frames[step]['tilePositionOfsets'].append(offset_t)
133143
nonbuildings += 1
134144

135145
if report:
136146
print(f"INFO: walls | pitch | moat: {nonbuildings}")
137147

138148
misc = 0
139149
for unitType in range(24):
150+
number = 0
140151
for entry in range(10):
141152
location = units[unitType, entry].item()
142153
if location == 0:
143154
continue
155+
offset_t = translate_offset(location, invert_x, invert_y)
144156
misc += 1
145-
miscItems.append({'itemType': unitType, 'positionOfset': location, 'number': entry})
157+
miscItems.append({ 'positionOfset': offset_t, 'itemType': unitType,'number': number})
158+
number += 1
146159

147160
if report:
148161
print(f"INFO: units | flags | brazier | misc: {misc}")

sourcehold/tool/convert/aiv/imports.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,31 @@
88
from importlib import resources as impresources
99
from sourcehold import resources
1010

11-
mapping_xyinversed_offset = np.zeros(shape=(AIV_WIDTH, AIV_HEIGHT), dtype='uint32')
12-
mapping_xy_offset = np.zeros(shape=(AIV_WIDTH, AIV_HEIGHT), dtype='uint32')
11+
# mapping_xyinversed_offset = np.zeros(shape=(AIV_WIDTH, AIV_HEIGHT), dtype='uint32')
12+
# mapping_xy_offset = np.zeros(shape=(AIV_WIDTH, AIV_HEIGHT), dtype='uint32')
1313

14-
offset = -1
15-
for x in x_range():
16-
for y in y_range(invert_y=False):
17-
offset += 1
18-
mapping_xy_offset[x, y] = offset
14+
# offset = -1
15+
# for x in x_range(invert_x=False):
16+
# for y in y_range(invert_y=False):
17+
# offset += 1
18+
# mapping_xy_offset[x, y] = offset
1919

20-
offset = -1
21-
for x in x_range():
22-
for y in y_range(invert_y=True):
23-
offset += 1
24-
mapping_xyinversed_offset[x, y] = offset
20+
# offset = -1
21+
# for x in x_range(invert_x=False):
22+
# for y in y_range(invert_y=True):
23+
# offset += 1
24+
# mapping_xyinversed_offset[x, y] = offset
2525

26-
def convert_offset(offset, invert_y=False):
27-
return (offset // AIV_WIDTH, offset % AIV_HEIGHT if not invert_y else (AIV_HEIGHT - 1) - (offset % AIV_HEIGHT))
26+
def convert_offset(offset, invert_y=False, invert_x=False):
27+
y = offset % AIV_HEIGHT if not invert_y else (AIV_HEIGHT - 1) - (offset % AIV_HEIGHT)
28+
x = offset // AIV_WIDTH if not invert_x else ((AIV_WIDTH - 1) - (offset // AIV_WIDTH))
29+
return (x, y)
2830

29-
def convert_offsets(offsets, invert_y=False):
31+
def convert_offsets(offsets, invert_y=False, invert_x=False):
3032
for loc in offsets:
31-
yield convert_offset(loc, invert_y=invert_y)
33+
yield convert_offset(loc, invert_y=invert_y, invert_x=invert_x)
3234

33-
def from_json(path: Union[str, None] = None, data: Union[Dict, None] = None, f=None, invert_y = True, report = False):
35+
def from_json(path: Union[str, None] = None, data: Union[Dict, None] = None, f=None, invert_y = False, invert_x = True, report = False):
3436
if not path and not data and not f:
3537
raise Exception()
3638

@@ -62,7 +64,7 @@ def from_json(path: Union[str, None] = None, data: Union[Dict, None] = None, f=N
6264
# Special type
6365
aivID = convertMapperEnumToAIVEnum(v = mapperID)
6466
locations = frame['tilePositionOfsets']
65-
for x, y in convert_offsets(locations, invert_y=invert_y):
67+
for x, y in convert_offsets(locations, invert_y=invert_y, invert_x=invert_x):
6668
constructions[x, y] = aivID
6769
steps[x, y] = step
6870
else:
@@ -74,7 +76,7 @@ def from_json(path: Union[str, None] = None, data: Union[Dict, None] = None, f=N
7476
if len(frame['tilePositionOfsets']) > 1:
7577
raise Exception(f'too many locations for a building: {frame["tilePositionOfsets"]}')
7678
location = frame['tilePositionOfsets'][0]
77-
x, y = convert_offset(location, invert_y=invert_y)
79+
x, y = convert_offset(location, invert_y=invert_y, invert_x=invert_x)
7880
constructions[x:(x+size),y:(y+size)] = aivID
7981
steps[x:(x+size),y:(y+size)] = step
8082
for miscItem in data['miscItems']:

sourcehold/tool/convert/aiv/info.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,9 @@ def get_units_matrix(data = None):
824824

825825
PAUSE_DELAY_AMOUNT_STRUCT_FORMAT = "<1i"
826826

827-
def x_range():
827+
def x_range(invert_x=False):
828+
if invert_x:
829+
return range(AIV_WIDTH-1, -1, -1)
828830
return range(AIV_WIDTH)
829831

830832
def y_range(invert_y=False):

0 commit comments

Comments
 (0)