Last active
October 25, 2020 06:09
-
-
Save Meshiest/deb920d27531a2fba5bff2befed39a32 to your computer and use it in GitHub Desktop.
Low effort text generator website for brickadia saves - must adhere to the format
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdn.jsdelivr.net/gh/meshiest/brs-js/dist/dist.js"></script> | |
<script src="https://gist.githack.com/Meshiest/2a253b88a514610772aa03625d41e23a/raw/bricktool.js"></script> | |
<h1>cake's 3am low effort text generator for brickadia</h1> | |
<p> | |
Click <a href="https://github.com/Meshiest/omegga-textgen/tree/master/fonts" target="_blank">here</a> for demo fonts. This is based on the <a href="https://github.com/Meshiest/omegga-textgen" target="_blank">omegga textgen plugin</a>. Read the code for this <a href="https://gist.github.com/Meshiest/deb920d27531a2fba5bff2befed39a32" target="_blank">here</a>. | |
</p> | |
<p> | |
You must select a valid save or you will not be able to generate text. See demo saves for the format | |
</p> | |
<table> | |
<tr> | |
<td><b>Input font</b></td> | |
<td> | |
<input id="fileInput" type="file"> | |
</td> | |
</tr> | |
<tr> | |
<td><b>Color (RGB 0-255)</b></td> | |
<td> | |
<input id="colorR" type="number" min="0" max="255" value="0" placeholder="R"> | |
<input id="colorG" type="number" min="0" max="255" value="0" placeholder="G"> | |
<input id="colorB" type="number" min="0" max="255" value="0" placeholder="B"> | |
</td> | |
</tr> | |
<tr> | |
<td><b>Spacing (1 stud = 10)</b></td> | |
<td> | |
<input id="spacing" type="number" min="0" value="10"> | |
</td> | |
</tr> | |
</table> | |
<div id="generateArea" style="display: none;"> | |
<h3>Enter text here.</h3> | |
<p>Single line only, just paste a really long line and split it yourself</p> | |
<input id="text" type="text"> | |
<button id="generateBtn">generate</button> <br/> | |
<a id="anchor" download="text.brs">Download</a> | |
</div> | |
<pre id="jsonElem"></pre> | |
<img src="https://i.imgur.com/jmfZMLC.png"> | |
<img src="https://i.imgur.com/e83XIDc.png"> | |
<img src="https://i.imgur.com/PRnfdcM.png"> | |
<script> | |
function parseFont(data) { | |
const $_ = $tool(data); | |
const startMarker = $_.find({asset: 'PB_DefaultBrick', size: [5, 5, 2], material: 'BMC_Glow', color: 0})[0]; | |
if (!startMarker) | |
throw 'missing start marker (1x1f white (greys 0) glow marker)'; | |
const endMarker = $_.find({asset: 'PB_DefaultBrick', size: [5, 5, 2], material: 'BMC_Glow', color: 7})[0]; | |
if (!endMarker) | |
throw 'missing end marker (1x1f black (greys 7) glow marker)'; | |
// determine which axis the characters are on | |
const axis = startMarker.position.findIndex((x, i) => x !== endMarker.position[i]); | |
// direction the character set is going | |
const delta = endMarker.position[axis] - startMarker.position[axis]; | |
// get the character plates | |
const characters = $_.find({asset: 'PB_DefaultBrick', material: 'BMC_Plastic', color: 0}) | |
// sort them based on distance from start marker | |
.sort((a, b) => | |
(a.position[axis] - b.position[axis])*delta | |
) | |
// get the bricks above the plate | |
.map(c => { | |
const size = c.rotation === 1 || c.rotation == 3 ? [c.size[1], c.size[0], c.size[2]] : c.size; | |
return { | |
bricks: $_.shifted($_.above(c), c.position.map(v => -v)), | |
width: size[axis] * 2, | |
height: size[1 - axis] * 2, | |
}; | |
}); | |
console.log('Found', characters.length, 'chars in character set'); | |
if (characters.length !== 95) { | |
console.warn('Character list: ' + Array.from({length: 95}).map((_, i) => String.fromCharCode(i + 32)).join('')); | |
throw 'not enough characters built.'; | |
} | |
// generate brick text from string | |
return (str='', {shift=[0, 0, 0], color=[0, 0, 0], spacing=10, centered=false}={}) => { | |
// break into characters, convert to ascii | |
const chars = str.split('').map(c => c.charCodeAt(0)).filter(c => c >= 32 && c <= 127); | |
let length = 0; | |
const output = []; | |
// if the text is centered, move the text to the left by half of the width | |
const fullWidth = chars.reduce((a, c) => a + characters[c - 32].width + spacing, -5); | |
if (centered) | |
length -= fullWidth/2; | |
// iterate through characters, adding kerning based on encoded character width | |
for (const c of chars) { | |
const { bricks, width } = characters[c - 32]; | |
// determine global offset | |
let shifted = [...shift]; | |
// add the kerning and existing length | |
shifted[axis] += (length + width/2) * Math.sign(delta); | |
// center this character | |
length += width + spacing; | |
// add it to the save | |
output.push(...$_.shifted(bricks, shifted)); | |
} | |
// set the color | |
for (const b of output) | |
b.color = [...color, 255]; | |
// save | |
return $_.write(output); | |
}; | |
} | |
fileInput.addEventListener('change', e => { | |
const file = e.target.files[0]; | |
if (file) { | |
// Read the file into a byte array | |
file.arrayBuffer() | |
.then(buff => { | |
const save = BRS.read(buff); | |
jsonElem.innerText = 'generating'; | |
// Log the save object | |
console.log(save); | |
const generator = parseFont(save); | |
generateArea.style.display = 'block'; | |
generateBtn.onclick = () => { | |
generator( | |
text.value, { | |
color: [colorR.value, colorG.value, colorB.value].map(n => parseInt(n)), | |
spacing: parseInt(spacing.value), | |
}, | |
); | |
} | |
}) | |
.catch(err => { | |
generateArea.style.display = 'none'; | |
// Display the error | |
jsonElem.innerText = 'Error: ' + (err.message || err); | |
}); | |
} | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment