Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Generate the rick roll animation for the Factorio screen!
const Blueprint = require('factorio-blueprint');
const PNG = require('png-js');
const inputs = Object.keys(Blueprint.getEntityData()).filter(key => !Blueprint.getEntityData()[key].combinator).slice(0, 60);
const bp = new Blueprint();
const FRAMES = 4230; // Number of images I had
const COL = 30; // Max height = COL * 4 or something
const LEFT = true; // Change so you can get the left and the right side
let prevPole = null;
for (let y = 0; y < COL/2; y++) {
for (let x = 0; x < FRAMES/COL/4; x++) {
const X = (y % 2 == 1 ? Math.ceil(FRAMES/COL/4) - x - 1 : x)*8 + 3;
const Y = y*7 + 3;
const pole = bp.createEntity('medium_electric_pole', { x: X, y: Y });
if (prevPole) {
pole.connect(prevPole);
pole.connect(prevPole, null, null, 'green');
}
prevPole = pole;
}
}
for (let i = 0; i < FRAMES; i++) {
((index) => {
PNG.decode('./img/'+(index+1)+'.png', pixels => {
frame(index, pixels);
});
})(i);
}
const THRESHHOLD = 256*3/2;
function parsePixels(pixels, left) {
const ret = {};
for (let y = 0; y < 60; y++) {
const item = inputs[y];
ret[item] = 0;
for (let x = (left ? 0 : 30); x < (left ? 30 : 60); x++) {
const index = y*240+x*4;
const total = pixels[index]+pixels[index+1]+pixels[index+2];
if (total > THRESHHOLD) ret[item] += Math.abs(1 << (left ? 29 - x : x - 30));
}
}
return ret;
}
function frame(id, pixels) {
const data = parsePixels(pixels, LEFT);
const keys = Object.keys(data);
let prev = null;
const mainX = Math.floor(id/COL);
const mainY = id % COL;
const X = mainX*2;
const Y = mainY*4 - Math.floor(mainY/2);
const poleX = Math.floor(mainX/4)*8 + 3;
const poleY = Math.floor(mainY/2)*7 + 3;
for (let i = 0; i < 4; i++) {
const myX = X + (i % 2 == 0 ? 0 : 1);
const myY = Y + (i < 2 ? 1 : 2);
const ent = bp.createEntity('constant_combinator', { x: myX, y: myY });
for (let j = 0; j < 15; j++) {
ent.setFilter(j+1, keys[i*15 + j], data[keys[i*15 + j]]);
}
if (prev) ent.connect(prev);
prev = ent;
}
bp.createEntity('decider_combinator', { x: X, y: Y, direction: 2 })
.connect(prev, 'in', null)
.connect(bp.findEntity({ x: poleX, y: poleY }), 'out', null, 'red')
.connect(bp.findEntity({ x: poleX, y: poleY }), 'in', null, 'green')
.setCondition({
left: 'signal_0',
operator: '=',
right: id+1,
out: 'signal_everything'
});
done();
}
var framesDone = 0;
function done() {
framesDone++;
if (framesDone == FRAMES) {
bp.center();
console.log(bp.encode());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment