brs-js 2.0.13 → 2.0.14
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/package.json +1 -1
- package/.babelrc +0 -5
- package/.prettierrc +0 -7
- package/debug/Conf Spacestation.brs +0 -0
- package/debug/Electrks_Feminine_Challenge.brs +0 -0
- package/debug/a5bricks.brs +0 -0
- package/debug/a5p2.2.brs +0 -0
- package/debug/a5p2.brs +0 -0
- package/debug/audio.brs +0 -0
- package/debug/brick a5.brs +0 -0
- package/debug/brick qa.brs +0 -0
- package/debug/brickparty.brs +0 -0
- package/debug/brsv10.brs +0 -0
- package/debug/brsv10brick.brs +0 -0
- package/debug/bruteforce.js +0 -254
- package/debug/click brick.brs +0 -0
- package/debug/clone.html +0 -36
- package/debug/clone.js +0 -33
- package/debug/ctf_tileset.brs +0 -0
- package/debug/ctf_tileset_5.brs +0 -0
- package/debug/evil.brs +0 -0
- package/debug/evilwrite.js +0 -390
- package/debug/foo.txt +0 -3080
- package/debug/kenko_big.brs +0 -0
- package/debug/light.brs +0 -0
- package/debug/out.json +0 -105
- package/debug/read.js +0 -30
- package/debug/readSpeed.js +0 -32
- package/debug/readTest.js +0 -45
- package/debug/temp.brs +0 -0
- package/debug/unicodeInteract.brs +0 -0
- package/debug/western.brs +0 -0
- package/examples/ATCFort.brs +0 -0
- package/examples/read_example.html +0 -34
- package/examples/read_example.js +0 -21
- package/examples/write_example.js +0 -25
- package/examples/write_planet.html +0 -144
- package/examples/write_simplex.html +0 -82
- package/examples/write_wedge_sphere.html +0 -173
- package/src/constants.ts +0 -6
- package/src/index.ts +0 -15
- package/src/read.ts +0 -57
- package/src/read.v1.ts +0 -99
- package/src/read.v10.ts +0 -185
- package/src/read.v2.ts +0 -102
- package/src/read.v3.ts +0 -111
- package/src/read.v4.ts +0 -112
- package/src/read.v8.ts +0 -172
- package/src/read.v9.ts +0 -181
- package/src/types.ts +0 -341
- package/src/utils.ts +0 -651
- package/src/uuid.ts +0 -78
- package/src/write.ts +0 -287
- package/test/lib.test.js +0 -51
- package/test/utils.test.js +0 -209
- package/tsconfig.json +0 -18
- package/webpack.config.js +0 -64
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<script src="https://cdn.jsdelivr.net/gh/meshiest/brs-js/dist/dist.js"></script>
|
|
3
|
-
<script src="https://cdn.jsdelivr.net/gh/josephg/noisejs/perlin.js"></script>
|
|
4
|
-
|
|
5
|
-
<a id="anchor" download="generated.brs">Download</a>
|
|
6
|
-
|
|
7
|
-
<script>
|
|
8
|
-
|
|
9
|
-
console.time('Generate');
|
|
10
|
-
|
|
11
|
-
// Generate fake UUID for terrain owner so you can /clearbricks terrain
|
|
12
|
-
const author = {
|
|
13
|
-
id: 'a8033bee-6c37-4118-b4a6-cecc1d966132',
|
|
14
|
-
name: 'terrain',
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
noise.seed(Math.random());
|
|
18
|
-
|
|
19
|
-
const size = 200;
|
|
20
|
-
const brickSize = 40;
|
|
21
|
-
|
|
22
|
-
// Build an array for the entire volume made of cubes
|
|
23
|
-
const locations = Array.from({length: size ** 3})
|
|
24
|
-
.map((_, i) => {
|
|
25
|
-
let obj = {
|
|
26
|
-
x: i % size,
|
|
27
|
-
y: Math.floor(i / size) % size,
|
|
28
|
-
z: Math.floor(i / size / size) % size,
|
|
29
|
-
width: 1,
|
|
30
|
-
depth: 1,
|
|
31
|
-
height: 1,
|
|
32
|
-
kind: 0,
|
|
33
|
-
material: 2,
|
|
34
|
-
rotation: 0,
|
|
35
|
-
};
|
|
36
|
-
obj.v = (
|
|
37
|
-
Math.max( // caves
|
|
38
|
-
Math.abs(noise.perlin3(obj.x / 30, obj.y / 30, obj.z / 30)),
|
|
39
|
-
Math.abs(noise.perlin3(obj.x / 30 + 9000, obj.y / 30 - 2000, obj.z / 30 + 4000))
|
|
40
|
-
) > 0.15 &&
|
|
41
|
-
Math.hypot(obj.x - size/2, obj.y - size/2, obj.z - size/2) < size/2 // sphere mask
|
|
42
|
-
) ? 1 : 0;
|
|
43
|
-
return obj;
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
// Get brick at position
|
|
47
|
-
const at2 = (x, y, z) =>
|
|
48
|
-
x < 0 || y < 0 || z < 0 || x >= size || y >= size || z >= size
|
|
49
|
-
? null
|
|
50
|
-
: locations[x + y * size + z * size * size];
|
|
51
|
-
|
|
52
|
-
// get if brick exists at position
|
|
53
|
-
const at = (x, y, z) => {
|
|
54
|
-
const brick = at2(x, y, z);
|
|
55
|
-
return (brick && brick.v) ? 1 : 0;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// Get a bit mask of the neighbors in West, North, East, South order
|
|
60
|
-
const getNeighbors = (x, y, z) => (at(x - 1, y, z) << 3) | (at(x, y - 1, z) << 2) | (at(x + 1, y, z) << 1) | (at(x, y + 1, z));
|
|
61
|
-
|
|
62
|
-
// convert corners to wedges
|
|
63
|
-
const wedgify = () => locations
|
|
64
|
-
.filter(obj => obj.v)
|
|
65
|
-
.forEach(obj => {
|
|
66
|
-
const {x, y, z} = obj;
|
|
67
|
-
const neighbors = getNeighbors(x, y, z);
|
|
68
|
-
|
|
69
|
-
// delta x/y variables are for increasing width of wedges
|
|
70
|
-
let dx = 0;
|
|
71
|
-
let dy = 0;
|
|
72
|
-
|
|
73
|
-
// handle each of the possible rotations on the Z axis
|
|
74
|
-
if (neighbors === 0b0011) {
|
|
75
|
-
obj.kind = 1;
|
|
76
|
-
obj.rotation = 2;
|
|
77
|
-
}
|
|
78
|
-
else if (neighbors === 0b1100) {
|
|
79
|
-
obj.kind = 1;
|
|
80
|
-
obj.rotation = 0;
|
|
81
|
-
}
|
|
82
|
-
else if (neighbors === 0b1001) {
|
|
83
|
-
obj.kind = 1;
|
|
84
|
-
obj.rotation = 3;
|
|
85
|
-
}
|
|
86
|
-
else if (neighbors === 0b0110) {
|
|
87
|
-
obj.kind = 1;
|
|
88
|
-
obj.rotation = 1;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// re-center wedges that got resized
|
|
92
|
-
if(obj.kind === 1) {
|
|
93
|
-
obj.width += Math.abs(dx);
|
|
94
|
-
obj.x = dx / 2 + x;
|
|
95
|
-
obj.depth += Math.abs(dy);
|
|
96
|
-
obj.y = dy / 2 + y;
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
wedgify();
|
|
101
|
-
|
|
102
|
-
// Hollow-out the middle by removing cubes surrounding
|
|
103
|
-
locations
|
|
104
|
-
.filter(obj => obj.v)
|
|
105
|
-
.forEach(obj => {
|
|
106
|
-
const {x, y, z} = obj;
|
|
107
|
-
const neighbors = [ // all neighboring cubes
|
|
108
|
-
at2(x, y, z + 1),
|
|
109
|
-
at2(x, y, z - 1),
|
|
110
|
-
at2(x - 1, y, z),
|
|
111
|
-
at2(x + 1, y, z),
|
|
112
|
-
at2(x, y - 1, z),
|
|
113
|
-
at2(x, y + 1, z),
|
|
114
|
-
];
|
|
115
|
-
|
|
116
|
-
// check if surrounded by bricks that exist and are not wedges
|
|
117
|
-
if(neighbors.every(n => n && n.v !== 0 && n.kind === 0)) {
|
|
118
|
-
obj.v = 2;
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
// Uncomment below if you want wedges on the inside (creates holes in some places)
|
|
123
|
-
|
|
124
|
-
/*
|
|
125
|
-
locations.filter(obj => obj.v === 2).forEach(obj => obj.v = 0);
|
|
126
|
-
wedgify();
|
|
127
|
-
*/
|
|
128
|
-
|
|
129
|
-
const save = {
|
|
130
|
-
author: author,
|
|
131
|
-
description: 'Cave Sphere',
|
|
132
|
-
map: 'JavaScript',
|
|
133
|
-
brick_owners: [author],
|
|
134
|
-
brick_assets: [
|
|
135
|
-
'PB_DefaultBrick',
|
|
136
|
-
'PB_DefaultSideWedge',
|
|
137
|
-
],
|
|
138
|
-
materials: [
|
|
139
|
-
'BMC_Ghost',
|
|
140
|
-
'BMC_Ghost_Fail',
|
|
141
|
-
'BMC_Plastic',
|
|
142
|
-
'BMC_Glow',
|
|
143
|
-
'BMC_Metallic',
|
|
144
|
-
'BMC_Hologram',
|
|
145
|
-
],
|
|
146
|
-
bricks: locations
|
|
147
|
-
.filter(o => o.v === 1)
|
|
148
|
-
.map(({x, y, z, kind, rotation, material, width, height, depth}) => ({
|
|
149
|
-
// give multiple dimensions in case we resize wedges
|
|
150
|
-
size: [brickSize * width, brickSize * depth, brickSize * height],
|
|
151
|
-
asset_name_index: kind,
|
|
152
|
-
material_index: material,
|
|
153
|
-
rotation,
|
|
154
|
-
// 3d color blobs that are kinda grey-ish
|
|
155
|
-
color: [
|
|
156
|
-
Math.floor(noise.perlin3(x / 50, y / 50, z / 50) * 80 + 100),
|
|
157
|
-
Math.floor(noise.perlin3(x / 50 - 3000, y / 50 - 3000, z / 50 + 200) * 80 + 100),
|
|
158
|
-
Math.floor(noise.perlin3(x / 50 + 2000, y / 50 + 2000, z / 50 - 2000) * 80 + 100),
|
|
159
|
-
255,
|
|
160
|
-
],
|
|
161
|
-
position: [
|
|
162
|
-
x * brickSize * 2,
|
|
163
|
-
y * brickSize * 2,
|
|
164
|
-
z * brickSize * 2,
|
|
165
|
-
],
|
|
166
|
-
})),
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
const blob = new Blob([new Uint8Array(BRS.write(save))]);
|
|
170
|
-
console.timeEnd('Generate');
|
|
171
|
-
anchor.href = URL.createObjectURL(blob);
|
|
172
|
-
|
|
173
|
-
</script>
|
package/src/constants.ts
DELETED
package/src/index.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import read from './read';
|
|
2
|
-
import write from './write';
|
|
3
|
-
import * as utils from './utils';
|
|
4
|
-
import * as constants from './constants';
|
|
5
|
-
import * as types from './types';
|
|
6
|
-
export * from './types';
|
|
7
|
-
|
|
8
|
-
// https://i.imgur.com/cv1fDWs.png
|
|
9
|
-
const brs = { read, write, utils, constants, types };
|
|
10
|
-
export { read, write, utils, constants, types };
|
|
11
|
-
export default brs;
|
|
12
|
-
|
|
13
|
-
if (typeof window !== 'undefined') {
|
|
14
|
-
(window as any).BRS = brs;
|
|
15
|
-
}
|
package/src/read.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { MAGIC } from './constants';
|
|
2
|
-
import readBrsV1 from './read.v1';
|
|
3
|
-
import readBrsV10 from './read.v10';
|
|
4
|
-
import readBrsV2 from './read.v2';
|
|
5
|
-
import readBrsV3 from './read.v3';
|
|
6
|
-
import readBrsV4 from './read.v4';
|
|
7
|
-
import readBrsV8 from './read.v8';
|
|
8
|
-
import readBrsV9 from './read.v9';
|
|
9
|
-
import { BRSBytes, ReadOptions, ReadSaveObject } from './types';
|
|
10
|
-
import { read } from './utils';
|
|
11
|
-
|
|
12
|
-
// Reads in a byte array to build a brs object
|
|
13
|
-
export default function readBrs(
|
|
14
|
-
rawBytes: Uint8Array,
|
|
15
|
-
options: ReadOptions = {}
|
|
16
|
-
): ReadSaveObject {
|
|
17
|
-
if (typeof options !== 'object') throw new Error('Invalid options');
|
|
18
|
-
|
|
19
|
-
// default enable brick reading
|
|
20
|
-
if (typeof options.bricks !== 'boolean') options.bricks = true;
|
|
21
|
-
|
|
22
|
-
// default disable preview (a5 only)
|
|
23
|
-
if (typeof options.preview !== 'boolean') options.preview = false;
|
|
24
|
-
|
|
25
|
-
// Determine if the first 3 bytes are equal to the Brickadia save magic bytes
|
|
26
|
-
if (
|
|
27
|
-
rawBytes[0] !== MAGIC[0] ||
|
|
28
|
-
rawBytes[1] !== MAGIC[1] ||
|
|
29
|
-
rawBytes[2] !== MAGIC[2]
|
|
30
|
-
) {
|
|
31
|
-
throw new Error('Invalid starting bytes');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const brsData = rawBytes as BRSBytes;
|
|
35
|
-
brsData.brsOffset = 3;
|
|
36
|
-
|
|
37
|
-
// Determine if the file version supported
|
|
38
|
-
const version = read.u16(brsData);
|
|
39
|
-
switch (version) {
|
|
40
|
-
case 1:
|
|
41
|
-
return readBrsV1(brsData, options);
|
|
42
|
-
case 2:
|
|
43
|
-
return readBrsV2(brsData, options);
|
|
44
|
-
case 3:
|
|
45
|
-
return readBrsV3(brsData, options);
|
|
46
|
-
case 4:
|
|
47
|
-
return readBrsV4(brsData, options);
|
|
48
|
-
case 8:
|
|
49
|
-
return readBrsV8(brsData, options);
|
|
50
|
-
case 9:
|
|
51
|
-
return readBrsV9(brsData, options);
|
|
52
|
-
case 10:
|
|
53
|
-
return readBrsV10(brsData, options);
|
|
54
|
-
default:
|
|
55
|
-
throw new Error('Unsupported version ' + version);
|
|
56
|
-
}
|
|
57
|
-
}
|
package/src/read.v1.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BRSBytes,
|
|
3
|
-
ReadOptions,
|
|
4
|
-
BrsV1,
|
|
5
|
-
UnrealColor,
|
|
6
|
-
BrickV1,
|
|
7
|
-
Vector,
|
|
8
|
-
} from './types';
|
|
9
|
-
import { bgra, read } from './utils';
|
|
10
|
-
|
|
11
|
-
// Reads in a byte array to build a brs object
|
|
12
|
-
export default function readBrsV1(
|
|
13
|
-
brsData: BRSBytes,
|
|
14
|
-
options: ReadOptions = {}
|
|
15
|
-
): BrsV1 {
|
|
16
|
-
// Read in Headers
|
|
17
|
-
const header1Data = read.compressed(brsData);
|
|
18
|
-
const header2Data = read.compressed(brsData);
|
|
19
|
-
|
|
20
|
-
const map = read.string(header1Data);
|
|
21
|
-
const author_name = read.string(header1Data);
|
|
22
|
-
const description = read.string(header1Data);
|
|
23
|
-
|
|
24
|
-
const author_id = read.uuid(header1Data);
|
|
25
|
-
|
|
26
|
-
const brick_count = read.i32(header1Data);
|
|
27
|
-
|
|
28
|
-
const mods = read.array(header2Data, read.string);
|
|
29
|
-
const brick_assets = read.array(header2Data, read.string);
|
|
30
|
-
const colors = read.array(
|
|
31
|
-
header2Data,
|
|
32
|
-
data => bgra(Array.from(read.bytes(data, 4))) as UnrealColor
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
// Read in bricks
|
|
36
|
-
let bricks: BrickV1[] = [];
|
|
37
|
-
|
|
38
|
-
const numAssets = Math.max(brick_assets.length, 2);
|
|
39
|
-
|
|
40
|
-
if (options.bricks) {
|
|
41
|
-
bricks = Array(brick_count);
|
|
42
|
-
const brickData = read.compressed(brsData);
|
|
43
|
-
const brickBits = read.bits(brickData);
|
|
44
|
-
|
|
45
|
-
// Brick reader
|
|
46
|
-
for (let i = 0; !brickBits.empty() && i < brick_count; i++) {
|
|
47
|
-
brickBits.align();
|
|
48
|
-
const asset_name_index = brickBits.int(numAssets);
|
|
49
|
-
const size: Vector = brickBits.bit()
|
|
50
|
-
? [
|
|
51
|
-
brickBits.uint_packed(),
|
|
52
|
-
brickBits.uint_packed(),
|
|
53
|
-
brickBits.uint_packed(),
|
|
54
|
-
]
|
|
55
|
-
: [0, 0, 0];
|
|
56
|
-
const position: Vector = [
|
|
57
|
-
brickBits.int_packed(),
|
|
58
|
-
brickBits.int_packed(),
|
|
59
|
-
brickBits.int_packed(),
|
|
60
|
-
];
|
|
61
|
-
|
|
62
|
-
const orientation = brickBits.int(24);
|
|
63
|
-
const direction = (orientation >> 2) % 6;
|
|
64
|
-
const rotation = orientation & 3;
|
|
65
|
-
const collision = brickBits.bit();
|
|
66
|
-
const visibility = brickBits.bit();
|
|
67
|
-
|
|
68
|
-
const color = brickBits.bit()
|
|
69
|
-
? bgra(brickBits.bytesArr(4) as [number, number, number, number])
|
|
70
|
-
: brickBits.int(colors.length);
|
|
71
|
-
|
|
72
|
-
bricks[i] = {
|
|
73
|
-
asset_name_index,
|
|
74
|
-
size,
|
|
75
|
-
collision,
|
|
76
|
-
position,
|
|
77
|
-
direction,
|
|
78
|
-
rotation,
|
|
79
|
-
visibility,
|
|
80
|
-
color,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return {
|
|
86
|
-
version: 1,
|
|
87
|
-
map,
|
|
88
|
-
description,
|
|
89
|
-
author: {
|
|
90
|
-
id: author_id,
|
|
91
|
-
name: author_name,
|
|
92
|
-
},
|
|
93
|
-
mods,
|
|
94
|
-
brick_assets,
|
|
95
|
-
colors,
|
|
96
|
-
bricks,
|
|
97
|
-
brick_count,
|
|
98
|
-
};
|
|
99
|
-
}
|
package/src/read.v10.ts
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AppliedComponent,
|
|
3
|
-
BrickV10,
|
|
4
|
-
BRSBytes,
|
|
5
|
-
BrsV10,
|
|
6
|
-
Collision,
|
|
7
|
-
ReadOptions,
|
|
8
|
-
UnrealColor,
|
|
9
|
-
User,
|
|
10
|
-
Vector,
|
|
11
|
-
} from './types';
|
|
12
|
-
import { bgra, read } from './utils';
|
|
13
|
-
|
|
14
|
-
// Reads in a byte array to build a brs object
|
|
15
|
-
export default function readBrsV10(
|
|
16
|
-
brsData: BRSBytes,
|
|
17
|
-
options: ReadOptions = {}
|
|
18
|
-
): BrsV10 {
|
|
19
|
-
// game version is included in saves >= v8
|
|
20
|
-
const game_version = read.i32(brsData);
|
|
21
|
-
|
|
22
|
-
// Read in Headers
|
|
23
|
-
const header1Data = read.compressed(brsData);
|
|
24
|
-
const header2Data = read.compressed(brsData);
|
|
25
|
-
|
|
26
|
-
const map = read.string(header1Data);
|
|
27
|
-
const author_name = read.string(header1Data);
|
|
28
|
-
const description = read.string(header1Data);
|
|
29
|
-
const author_id = read.uuid(header1Data);
|
|
30
|
-
const host: User = {
|
|
31
|
-
name: read.string(header1Data),
|
|
32
|
-
id: read.uuid(header1Data),
|
|
33
|
-
};
|
|
34
|
-
const save_time = read.bytes(header1Data, 8);
|
|
35
|
-
|
|
36
|
-
const brick_count = read.i32(header1Data);
|
|
37
|
-
|
|
38
|
-
const mods = read.array(header2Data, read.string);
|
|
39
|
-
const brick_assets = read.array(header2Data, read.string);
|
|
40
|
-
const colors = read.array(
|
|
41
|
-
header2Data,
|
|
42
|
-
data => bgra(Array.from(read.bytes(data, 4))) as UnrealColor
|
|
43
|
-
);
|
|
44
|
-
const materials = read.array(header2Data, read.string);
|
|
45
|
-
|
|
46
|
-
const brick_owners = read.array(header2Data, data => ({
|
|
47
|
-
id: read.uuid(data),
|
|
48
|
-
name: read.string(data),
|
|
49
|
-
bricks: read.i32(data),
|
|
50
|
-
}));
|
|
51
|
-
|
|
52
|
-
const physical_materials = read.array(header2Data, read.string);
|
|
53
|
-
|
|
54
|
-
// check for preview byte
|
|
55
|
-
let preview = null;
|
|
56
|
-
if (read.bytes(brsData, 1)[0]) {
|
|
57
|
-
const len = read.i32(brsData);
|
|
58
|
-
if (options.preview) {
|
|
59
|
-
preview = read.bytes(brsData, len);
|
|
60
|
-
} else {
|
|
61
|
-
brsData.brsOffset += len;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Read in bricks
|
|
66
|
-
let bricks: BrickV10[] = [];
|
|
67
|
-
const components: BrsV10['components'] = {};
|
|
68
|
-
|
|
69
|
-
const numPhysMats = Math.max(physical_materials.length, 2);
|
|
70
|
-
const numMats = Math.max(materials.length, 2);
|
|
71
|
-
const numAssets = Math.max(brick_assets.length, 2);
|
|
72
|
-
|
|
73
|
-
if (options.bricks) {
|
|
74
|
-
bricks = Array(brick_count);
|
|
75
|
-
const brickData = read.compressed(brsData);
|
|
76
|
-
const brickBits = read.bits(brickData);
|
|
77
|
-
|
|
78
|
-
// Brick reader
|
|
79
|
-
for (let i = 0; !brickBits.empty() && i < brick_count; i++) {
|
|
80
|
-
brickBits.align();
|
|
81
|
-
const asset_name_index = brickBits.int(numAssets);
|
|
82
|
-
const size: Vector = brickBits.bit()
|
|
83
|
-
? [
|
|
84
|
-
brickBits.uint_packed(),
|
|
85
|
-
brickBits.uint_packed(),
|
|
86
|
-
brickBits.uint_packed(),
|
|
87
|
-
]
|
|
88
|
-
: [0, 0, 0];
|
|
89
|
-
const position: Vector = [
|
|
90
|
-
brickBits.int_packed(),
|
|
91
|
-
brickBits.int_packed(),
|
|
92
|
-
brickBits.int_packed(),
|
|
93
|
-
];
|
|
94
|
-
|
|
95
|
-
const orientation = brickBits.int(24);
|
|
96
|
-
const direction = (orientation >> 2) % 6;
|
|
97
|
-
const rotation = orientation & 3;
|
|
98
|
-
const collision: Collision = {
|
|
99
|
-
player: brickBits.bit(),
|
|
100
|
-
weapon: brickBits.bit(),
|
|
101
|
-
interaction: brickBits.bit(),
|
|
102
|
-
tool: brickBits.bit(),
|
|
103
|
-
};
|
|
104
|
-
const visibility = brickBits.bit();
|
|
105
|
-
const material_index = brickBits.int(numMats);
|
|
106
|
-
const physical_index = brickBits.int(numPhysMats);
|
|
107
|
-
const material_intensity = brickBits.int(11);
|
|
108
|
-
const color = brickBits.bit()
|
|
109
|
-
? (brickBits.bytesArr(3) as [number, number, number])
|
|
110
|
-
: brickBits.int(colors.length);
|
|
111
|
-
|
|
112
|
-
const owner_index = brickBits.uint_packed();
|
|
113
|
-
|
|
114
|
-
bricks[i] = {
|
|
115
|
-
asset_name_index,
|
|
116
|
-
size,
|
|
117
|
-
position,
|
|
118
|
-
direction,
|
|
119
|
-
rotation,
|
|
120
|
-
collision: collision as Collision,
|
|
121
|
-
visibility,
|
|
122
|
-
material_index,
|
|
123
|
-
physical_index,
|
|
124
|
-
material_intensity,
|
|
125
|
-
color,
|
|
126
|
-
owner_index,
|
|
127
|
-
components: {},
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const componentData = read.compressed(brsData);
|
|
132
|
-
const numBricks = Math.max(bricks.length, 2);
|
|
133
|
-
|
|
134
|
-
read.each(componentData, data => {
|
|
135
|
-
// read component name
|
|
136
|
-
const name = read.string(data);
|
|
137
|
-
|
|
138
|
-
// read component body
|
|
139
|
-
const bits = read.bits(read.bytes(data, read.i32(data)));
|
|
140
|
-
|
|
141
|
-
const version = read.i32(bits.bytes(4));
|
|
142
|
-
// list of bricks
|
|
143
|
-
const brick_indices = bits.array(() => bits.int(numBricks));
|
|
144
|
-
|
|
145
|
-
// list of name, type properties
|
|
146
|
-
const properties = bits.array(() => [bits.string(), bits.string()]);
|
|
147
|
-
|
|
148
|
-
// read components for each brick
|
|
149
|
-
for (const i of brick_indices) {
|
|
150
|
-
const props: AppliedComponent = {};
|
|
151
|
-
for (const [name, type] of properties) props[name] = bits.unreal(type);
|
|
152
|
-
bricks[i].components[name] = props;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
components[name] = {
|
|
156
|
-
version,
|
|
157
|
-
brick_indices,
|
|
158
|
-
properties: Object.fromEntries(properties),
|
|
159
|
-
};
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return {
|
|
164
|
-
version: 10,
|
|
165
|
-
game_version,
|
|
166
|
-
map,
|
|
167
|
-
description,
|
|
168
|
-
author: {
|
|
169
|
-
id: author_id,
|
|
170
|
-
name: author_name,
|
|
171
|
-
},
|
|
172
|
-
host,
|
|
173
|
-
mods,
|
|
174
|
-
brick_assets,
|
|
175
|
-
colors,
|
|
176
|
-
materials,
|
|
177
|
-
brick_owners,
|
|
178
|
-
physical_materials,
|
|
179
|
-
preview,
|
|
180
|
-
bricks,
|
|
181
|
-
brick_count,
|
|
182
|
-
save_time,
|
|
183
|
-
components,
|
|
184
|
-
};
|
|
185
|
-
}
|
package/src/read.v2.ts
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BRSBytes,
|
|
3
|
-
ReadOptions,
|
|
4
|
-
BrsV2,
|
|
5
|
-
UnrealColor,
|
|
6
|
-
BrickV2,
|
|
7
|
-
Vector,
|
|
8
|
-
} from './types';
|
|
9
|
-
import { bgra, read } from './utils';
|
|
10
|
-
|
|
11
|
-
// Reads in a byte array to build a brs object
|
|
12
|
-
export default function readBrsV2(
|
|
13
|
-
brsData: BRSBytes,
|
|
14
|
-
options: ReadOptions = {}
|
|
15
|
-
): BrsV2 {
|
|
16
|
-
// Read in Headers
|
|
17
|
-
const header1Data = read.compressed(brsData);
|
|
18
|
-
const header2Data = read.compressed(brsData);
|
|
19
|
-
|
|
20
|
-
const map = read.string(header1Data);
|
|
21
|
-
const author_name = read.string(header1Data);
|
|
22
|
-
const description = read.string(header1Data);
|
|
23
|
-
const author_id = read.uuid(header1Data);
|
|
24
|
-
|
|
25
|
-
const brick_count = read.i32(header1Data);
|
|
26
|
-
|
|
27
|
-
const mods = read.array(header2Data, read.string);
|
|
28
|
-
const brick_assets = read.array(header2Data, read.string);
|
|
29
|
-
const colors = read.array(
|
|
30
|
-
header2Data,
|
|
31
|
-
data => bgra(Array.from(read.bytes(data, 4))) as UnrealColor
|
|
32
|
-
);
|
|
33
|
-
const materials = read.array(header2Data, read.string);
|
|
34
|
-
|
|
35
|
-
// Read in bricks
|
|
36
|
-
let bricks: BrickV2[] = [];
|
|
37
|
-
|
|
38
|
-
const numAssets = Math.max(brick_assets.length, 2);
|
|
39
|
-
|
|
40
|
-
if (options.bricks) {
|
|
41
|
-
bricks = Array(brick_count);
|
|
42
|
-
const brickData = read.compressed(brsData);
|
|
43
|
-
const brickBits = read.bits(brickData);
|
|
44
|
-
|
|
45
|
-
// Brick reader
|
|
46
|
-
for (let i = 0; !brickBits.empty() && i < brick_count; i++) {
|
|
47
|
-
brickBits.align();
|
|
48
|
-
const asset_name_index = brickBits.int(numAssets);
|
|
49
|
-
const size: Vector = brickBits.bit()
|
|
50
|
-
? [
|
|
51
|
-
brickBits.uint_packed(),
|
|
52
|
-
brickBits.uint_packed(),
|
|
53
|
-
brickBits.uint_packed(),
|
|
54
|
-
]
|
|
55
|
-
: [0, 0, 0];
|
|
56
|
-
const position: Vector = [
|
|
57
|
-
brickBits.int_packed(),
|
|
58
|
-
brickBits.int_packed(),
|
|
59
|
-
brickBits.int_packed(),
|
|
60
|
-
];
|
|
61
|
-
|
|
62
|
-
const orientation = brickBits.int(24);
|
|
63
|
-
const direction = (orientation >> 2) % 6;
|
|
64
|
-
const rotation = orientation & 3;
|
|
65
|
-
const collision = brickBits.bit();
|
|
66
|
-
const visibility = brickBits.bit();
|
|
67
|
-
const material_index = brickBits.bit() ? brickBits.uint_packed() : 1;
|
|
68
|
-
|
|
69
|
-
const color = brickBits.bit()
|
|
70
|
-
? bgra(brickBits.bytesArr(4) as [number, number, number, number])
|
|
71
|
-
: brickBits.int(colors.length);
|
|
72
|
-
|
|
73
|
-
bricks[i] = {
|
|
74
|
-
asset_name_index,
|
|
75
|
-
size,
|
|
76
|
-
position,
|
|
77
|
-
direction,
|
|
78
|
-
rotation,
|
|
79
|
-
collision,
|
|
80
|
-
visibility,
|
|
81
|
-
material_index,
|
|
82
|
-
color,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
version: 2,
|
|
89
|
-
map,
|
|
90
|
-
description,
|
|
91
|
-
author: {
|
|
92
|
-
id: author_id,
|
|
93
|
-
name: author_name,
|
|
94
|
-
},
|
|
95
|
-
mods,
|
|
96
|
-
brick_assets,
|
|
97
|
-
colors,
|
|
98
|
-
materials,
|
|
99
|
-
bricks,
|
|
100
|
-
brick_count,
|
|
101
|
-
};
|
|
102
|
-
}
|