human safety mod
This commit is contained in:
parent
41364c1a5b
commit
fcfc361d91
|
|
@ -0,0 +1,899 @@
|
|||
elements.human.tick = function(pixel) {
|
||||
if (isEmpty(pixel.x, pixel.y+1)) {
|
||||
createPixel("body", pixel.x, pixel.y+1);
|
||||
var color = pixel.color;
|
||||
changePixel(pixel,"head");
|
||||
pixel.color = color;
|
||||
if (pixel.bodyColor) {
|
||||
pixelMap[pixel.x][pixel.y+1].color = pixel.bodyColor;
|
||||
}
|
||||
}
|
||||
else if (isEmpty(pixel.x, pixel.y-1)) {
|
||||
createPixel("head", pixel.x, pixel.y-1);
|
||||
pixelMap[pixel.x][pixel.y-1].color = pixel.color;
|
||||
changePixel(pixel,"body");
|
||||
if (pixel.bodyColor) {
|
||||
pixel.color = pixel.bodyColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elements.body.tick = function(pixel) {
|
||||
if (tryMove(pixel, pixel.x, pixel.y+1)) { // Fall
|
||||
if (!isEmpty(pixel.x, pixel.y-2, true)) { // Drag head down
|
||||
var headpixel = pixelMap[pixel.x][pixel.y-2];
|
||||
if (headpixel.element === "head") {
|
||||
if (isEmpty(pixel.x, pixel.y-1)) {
|
||||
movePixel(pixelMap[pixel.x][pixel.y-2], pixel.x, pixel.y-1);
|
||||
}
|
||||
else {
|
||||
swapPixels(pixelMap[pixel.x][pixel.y-2], pixelMap[pixel.x][pixel.y-1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
doHeat(pixel);
|
||||
doBurning(pixel);
|
||||
doElectricity(pixel);
|
||||
if (pixel.dead) {
|
||||
// Turn into rotten_meat if pixelTicks-dead > 500
|
||||
if (pixelTicks-pixel.dead > 200 && Math.random() < 0.1) {
|
||||
changePixel(pixel,"rotten_meat");
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Find the head
|
||||
if (!isEmpty(pixel.x, pixel.y-1, true) && pixelMap[pixel.x][pixel.y-1].element == "head") {
|
||||
var head = pixelMap[pixel.x][pixel.y-1];
|
||||
if (head.dead) { // If head is dead, kill body
|
||||
pixel.dead = head.dead;
|
||||
}
|
||||
else if (head.panic > 0) {
|
||||
pixel.panic = head.panic;
|
||||
delete head.panic;
|
||||
}
|
||||
}
|
||||
else { var head = null }
|
||||
if (head && Math.random() < 0.25) {
|
||||
let y = Math.random() < 0.5 ? 0 : -1;
|
||||
for (let x = 1; x < 10; x++) {
|
||||
let x2 = pixel.x+(x*pixel.dir);
|
||||
let y2 = pixel.y+y;
|
||||
if (!isEmpty(x2,y2,true)) {
|
||||
let seenPixel = pixelMap[x2][y2];
|
||||
if (elements.human.reactions[seenPixel.element] && elements.human.reactions[seenPixel.element].attr1 && elements.human.reactions[seenPixel.element].attr1.panic) {
|
||||
pixel.panic += elements.human.reactions[seenPixel.element].attr1.panic;
|
||||
pixel.dir *= -1;
|
||||
break;
|
||||
}
|
||||
else if (seenPixel.dead || seenPixel.temp > 200) {
|
||||
pixel.panic += 5;
|
||||
pixel.dir *= -1;
|
||||
if (seenPixel.panic) delete seenPixel.panic;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pixel.burning) {
|
||||
pixel.panic += 0.1;
|
||||
if (head && pixelTicks-pixel.burnStart > 240) {
|
||||
pixel.color = head.color;
|
||||
}
|
||||
}
|
||||
if (pixel.charge) {
|
||||
pixel.panic += 1;
|
||||
}
|
||||
else if (pixel.panic > 0) {
|
||||
pixel.panic -= 0.1;
|
||||
if (pixel.panic < 0) { pixel.panic = 0; }
|
||||
else if (pixel.panic > 50) { pixel.panic = 50; }
|
||||
}
|
||||
|
||||
if (isEmpty(pixel.x, pixel.y-1)) {
|
||||
// create blood if decapitated 10% chance
|
||||
if (Math.random() < 0.1 && !pixel.charge) {
|
||||
createPixel("blood", pixel.x, pixel.y-1);
|
||||
// set dead to true 15% chance
|
||||
if (Math.random() < 0.15) {
|
||||
pixel.dead = pixelTicks;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (head === null) { return }
|
||||
else if (Math.random() < 0.1*(isEmpty(pixel.x, pixel.y+1) ? 1 : pixel.panic+1)) { // Move 10% chance
|
||||
var movesToTry = [
|
||||
[1*pixel.dir,0],
|
||||
[1*pixel.dir,-1],
|
||||
];
|
||||
let moved = false;
|
||||
// While movesToTry is not empty, tryMove(pixel, x, y) with a random move, then remove it. if tryMove returns true, break.
|
||||
while (movesToTry.length > 0) {
|
||||
var move = movesToTry.splice(Math.floor(Math.random() * movesToTry.length), 1)[0];
|
||||
if (isEmpty(pixel.x+move[0], pixel.y+move[1]-1)) {
|
||||
var origx = pixel.x+move[0];
|
||||
var origy = pixel.y+move[1];
|
||||
if (tryMove(pixel, pixel.x+move[0], pixel.y+move[1]) && pixel.x===origx && pixel.y===origy) {
|
||||
movePixel(head, head.x+move[0], head.y+move[1]);
|
||||
moved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!isEmpty(pixel.x+move[0], pixel.y+move[1], true)) {
|
||||
var hitPixel = pixelMap[pixel.x+move[0]][pixel.y+move[1]];
|
||||
if (hitPixel.element === "body" || hitPixel.element === "head" && hitPixel.panic < pixel.panic) {
|
||||
// interact with other human
|
||||
hitPixel.panic = pixel.panic;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 15% chance to change direction
|
||||
if (Math.random() < 0.15 || !moved) {
|
||||
pixel.dir *= -1;
|
||||
}
|
||||
// homeostasis
|
||||
if (pixel.temp > 37) { pixel.temp -= 1; }
|
||||
else if (pixel.temp < 37) { pixel.temp += 1; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
elements.portal_in.tick = function(pixel) {
|
||||
// if (Math.random() > 0.1) return;
|
||||
if (!ticktemp.portal_out) ticktemp.portal_out = {};
|
||||
let channel = parseInt(pixel.channel) || 0;
|
||||
if (!ticktemp.portal_out[channel]) {
|
||||
ticktemp.portal_out[channel] = currentPixels.filter((p) => {
|
||||
return elements[p.element].id === elements.portal_out.id && (
|
||||
isEmpty(p.x,p.y+1) || isEmpty(p.x,p.y-1) ||
|
||||
isEmpty(p.x+1,p.y) || isEmpty(p.x-1,p.y)
|
||||
) &&
|
||||
(parseInt(p.channel) || 0) === parseInt(channel)
|
||||
});
|
||||
}
|
||||
if (ticktemp.portal_out[channel].length) {
|
||||
shuffleArray(squareCoordsShuffle);
|
||||
let r;
|
||||
for (var i = 0; i < squareCoordsShuffle.length; i++) {
|
||||
var coord = squareCoordsShuffle[i];
|
||||
var x = pixel.x+coord[0];
|
||||
var y = pixel.y+coord[1];
|
||||
if (!isEmpty(x,y,true) && elements[pixelMap[x][y].element].movable) {
|
||||
r = pixelMap[x][y];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r !== undefined || pixel.charge) {
|
||||
let portal_out = choose(ticktemp.portal_out[channel]);
|
||||
if (portal_out.del) return;
|
||||
if (r !== undefined) {
|
||||
shuffleArray(squareCoordsShuffle);
|
||||
for (var j = 0; j < squareCoordsShuffle.length; j++) {
|
||||
var coord2 = squareCoordsShuffle[j];
|
||||
var x2 = portal_out.x+coord2[0];
|
||||
var y2 = portal_out.y+coord2[1];
|
||||
if (isEmpty(x2,y2) && r.element !== "head" && r.element !== "body") {
|
||||
tryMove(r,x2,y2);
|
||||
}
|
||||
else if (isEmpty(x2,y2) && (r.element === "head" || r.element === "body")) {
|
||||
if (r.element === "head" && !isEmpty(r.x,r.y+1)) {
|
||||
if (pixelMap[r.x][r.y+1].element === "body") {
|
||||
r.element = "human"
|
||||
r.bodyColor = pixelMap[r.x][r.y+1].color
|
||||
deletePixel(r.x,r.y+1)
|
||||
tryMove(r,x2,y2);
|
||||
}
|
||||
else {
|
||||
tryMove(r,x2,y2);
|
||||
}
|
||||
}
|
||||
else if (r.element === "body" && !isEmpty(r.x,r.y-1)) {
|
||||
if (pixelMap[r.x][r.y-1].element === "head") {
|
||||
r.element = "human"
|
||||
r.bodyColor = r.color
|
||||
r.color = pixelMap[r.x][r.y-1].color
|
||||
deletePixel(r.x,r.y-1)
|
||||
tryMove(r,x2,y2);
|
||||
}
|
||||
else {
|
||||
tryMove(r,x2,y2);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pixel.charge && !portal_out.charge && !portal_out.chargeCD) {
|
||||
portal_out.charge = pixel.charge;
|
||||
}
|
||||
}
|
||||
};
|
||||
doElectricity(pixel);
|
||||
}
|
||||
|
||||
elements.pipe.tick = function(pixel) {
|
||||
if (!pixel.stage && pixelTicks-pixel.start > 60) {
|
||||
for (var i = 0; i < squareCoords.length; i++) {
|
||||
var coord = squareCoords[i];
|
||||
var x = pixel.x+coord[0];
|
||||
var y = pixel.y+coord[1];
|
||||
if (!isEmpty(x,y,true) && elements[pixelMap[x][y].element].movable) {
|
||||
deletePixel(x,y)
|
||||
}
|
||||
if (isEmpty(x,y)) {
|
||||
createPixel("pipe_wall",x,y);
|
||||
}
|
||||
}
|
||||
pixel.stage = 1;
|
||||
}
|
||||
else if (pixel.stage === 1 && pixelTicks-pixel.start > 70) { //uninitialized
|
||||
for (var i = 0; i < adjacentCoords.length; i++) {
|
||||
var coord = adjacentCoords[i];
|
||||
var x = pixel.x+coord[0];
|
||||
var y = pixel.y+coord[1];
|
||||
if (isEmpty(x,y)) {
|
||||
pixel.stage = 2; //blue
|
||||
pixel.color = pixelColorPick(pixel,"#000036");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pixel.stage > 1 && pixelTicks % 3 === pixel.stage-2) { //initialized
|
||||
for (var i = 0; i < squareCoords.length; i++) {
|
||||
var coord = squareCoords[i];
|
||||
var x = pixel.x+coord[0];
|
||||
var y = pixel.y+coord[1];
|
||||
if (!isEmpty(x,y,true) && pixelMap[x][y].element === "pipe") {
|
||||
var newPixel = pixelMap[x][y];
|
||||
if (newPixel.stage === 1) {
|
||||
var newColor;
|
||||
switch (pixel.stage) {
|
||||
case 2: newPixel.stage = 3; newColor = "#003600"; break; //green
|
||||
case 3: newPixel.stage = 4; newColor = "#360000"; break; //red
|
||||
case 4: newPixel.stage = 2; newColor = "#000036"; break; //blue
|
||||
}
|
||||
newPixel.color = pixelColorPick(newPixel,newColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
var moved = false;
|
||||
shuffleArray(squareCoordsShuffle);
|
||||
for (var i = 0; i < squareCoordsShuffle.length; i++) {
|
||||
var coord = squareCoordsShuffle[i];
|
||||
var x = pixel.x+coord[0];
|
||||
var y = pixel.y+coord[1];
|
||||
if (!isEmpty(x,y,true)) {
|
||||
var newPixel = pixelMap[x][y];
|
||||
if (newPixel.element === "pipe") {
|
||||
var nextStage;
|
||||
switch (pixel.stage) {
|
||||
case 2: nextStage = 4; break; //green
|
||||
case 3: nextStage = 2; break; //red
|
||||
case 4: nextStage = 3; break; //blue
|
||||
}
|
||||
if (pixel.con && !newPixel.con && newPixel.stage === nextStage) { //transfer to adjacent pipe
|
||||
newPixel.con = pixel.con;
|
||||
newPixel.con.x = newPixel.x;
|
||||
newPixel.con.y = newPixel.y;
|
||||
pixel.con = null;
|
||||
moved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!pixel.con && elements[newPixel.element].movable && newPixel.element !== "head" && newPixel.element !== "body") { //suck up pixel
|
||||
pixel.con = newPixel;
|
||||
deletePixel(newPixel.x,newPixel.y);
|
||||
pixel.con.x = pixel.x;
|
||||
pixel.con.y = pixel.y;
|
||||
pixel.con.del;
|
||||
moved = true;
|
||||
break;
|
||||
}
|
||||
else if (!pixel.con && elements[newPixel.element].movable && (newPixel.element === "head" || newPixel.element === "body")) {
|
||||
if (newPixel.element === "head") {
|
||||
if (!isEmpty(newPixel.x,newPixel.y+1)) {
|
||||
if (pixelMap[newPixel.x][newPixel.y+1].element === "body") {
|
||||
newPixel.element = "human"
|
||||
newPixel.bodyColor = pixelMap[newPixel.x][newPixel.y+1].color
|
||||
deletePixel(newPixel.x,newPixel.y+1)
|
||||
pixel.con = newPixel;
|
||||
deletePixel(newPixel.x,newPixel.y);
|
||||
pixel.con.x = pixel.x;
|
||||
pixel.con.y = pixel.y;
|
||||
pixel.con.del;
|
||||
moved = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
pixel.con = newPixel;
|
||||
deletePixel(newPixel.x,newPixel.y);
|
||||
pixel.con.x = pixel.x;
|
||||
pixel.con.y = pixel.y;
|
||||
pixel.con.del;
|
||||
moved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pixel.con = newPixel;
|
||||
deletePixel(newPixel.x,newPixel.y);
|
||||
pixel.con.x = pixel.x;
|
||||
pixel.con.y = pixel.y;
|
||||
pixel.con.del;
|
||||
moved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (newPixel.element === "body") {
|
||||
if (!isEmpty(newPixel.x,newPixel.y-1)) {
|
||||
if (pixelMap[newPixel.x][newPixel.y-1].element === "head") {
|
||||
newPixel.element = "human"
|
||||
newPixel.bodyColor = newPixel.color
|
||||
newPixel.color = pixelMap[newPixel.x][newPixel.y-1].color
|
||||
deletePixel(newPixel.x,newPixel.y-1)
|
||||
pixel.con = newPixel;
|
||||
deletePixel(newPixel.x,newPixel.y);
|
||||
pixel.con.x = pixel.x;
|
||||
pixel.con.y = pixel.y;
|
||||
pixel.con.del;
|
||||
moved = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
pixel.con = newPixel;
|
||||
deletePixel(newPixel.x,newPixel.y);
|
||||
pixel.con.x = pixel.x;
|
||||
pixel.con.y = pixel.y;
|
||||
pixel.con.del;
|
||||
moved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pixel.con = newPixel;
|
||||
deletePixel(newPixel.x,newPixel.y);
|
||||
pixel.con.x = pixel.x;
|
||||
pixel.con.y = pixel.y;
|
||||
pixel.con.del;
|
||||
moved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pixel.con = newPixel;
|
||||
deletePixel(newPixel.x,newPixel.y);
|
||||
pixel.con.x = pixel.x;
|
||||
pixel.con.y = pixel.y;
|
||||
pixel.con.del;
|
||||
moved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pixel.con && !moved) { // move to same stage if none other
|
||||
for (var i = 0; i < squareCoordsShuffle.length; i++) {
|
||||
var coord = squareCoordsShuffle[i];
|
||||
var x = pixel.x+coord[0];
|
||||
var y = pixel.y+coord[1];
|
||||
if (isEmpty(x,y)) {
|
||||
delete pixel.con.del;
|
||||
pixel.con.x = x;
|
||||
pixel.con.y = y;
|
||||
pixelMap[x][y] = pixel.con;
|
||||
currentPixels.push(pixel.con);
|
||||
pixel.con = null;
|
||||
break;
|
||||
}
|
||||
if (!isEmpty(x,y,true) && pixelMap[x][y].element === "pipe") {
|
||||
var newPixel = pixelMap[x][y];
|
||||
if (pixel.con && !newPixel.con && newPixel.stage === pixel.stage) {
|
||||
newPixel.con = pixel.con;
|
||||
newPixel.con.x = newPixel.x;
|
||||
newPixel.con.y = newPixel.y;
|
||||
pixel.con = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
doDefaults(pixel);
|
||||
}
|
||||
|
||||
elements.drag.tool = function(pixel) {
|
||||
if (dragStart === null) {
|
||||
dragStart = pixelTicks;
|
||||
draggingPixels = [];
|
||||
}
|
||||
if (pixelTicks === dragStart && !pixel.drag && (elements[pixel.element].movable || shiftDown) && pixel.element !== "head") {
|
||||
pixel.drag = true;
|
||||
draggingPixels.push(pixel);
|
||||
}
|
||||
}
|
||||
|
||||
elements.drag.perTick = function() {
|
||||
if (!draggingPixels) { return; }
|
||||
for (var j = 0; j < (shiftDown ? 3 : 1); j++) {
|
||||
for (var i = 0; i < draggingPixels.length; i++) {
|
||||
var pixel = draggingPixels[i];
|
||||
if (pixel.del) { continue }
|
||||
const x = pixel.x;
|
||||
const y = pixel.y;
|
||||
const [mX, mY] = [mousePos.x, mousePos.y];
|
||||
const empty = checkForEmptyPixels(x, y);
|
||||
let bestVal = Math.sqrt(Math.pow(mX - x, 2) + Math.pow(mY - y, 2));
|
||||
let best = null;
|
||||
for (const pixelPair of empty) {
|
||||
const x_ = x + pixelPair[0];
|
||||
const y_ = y + pixelPair[1];
|
||||
const c = Math.sqrt(Math.pow(mX - x_, 2) + Math.pow(mY - y_, 2));
|
||||
if (c < bestVal) {
|
||||
bestVal = c;
|
||||
best = pixelPair;
|
||||
}
|
||||
}
|
||||
if (best) {
|
||||
if (pixel.element !== "body") {
|
||||
tryMove(pixel, x + best[0], y + best[1], undefined, true);
|
||||
}
|
||||
else if (pixel.element === "body") {
|
||||
if (!isEmpty(pixel.x,pixel.y-1)) {
|
||||
var headPixel = pixelMap[pixel.x][pixel.y-1]
|
||||
if (headPixel.element === "head") {
|
||||
if (isEmpty(x + best[0], y + best[1] - 1)) {
|
||||
tryMove(headPixel, x + best[0], y + best[1] - 1, undefined, true);
|
||||
tryMove(pixel, x + best[0], y + best[1], undefined, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {tryMove(pixel, x + best[0], y + best[1], undefined, true);}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mouse1Action = function(e,mouseX=undefined,mouseY=undefined,startPos) {
|
||||
if (currentElement === "erase") { mouse2Action(e,mouseX,mouseY,startPos); return; }
|
||||
else if (currentElement === "pick") { mouseMiddleAction(e,mouseX,mouseY); return; }
|
||||
// If x and y are undefined, get the mouse position
|
||||
if (mouseX === undefined && mouseY === undefined) {
|
||||
// var canvas = document.getElementById("game");
|
||||
// var ctx = canvas.getContext("2d");
|
||||
lastPos = mousePos;
|
||||
mousePos = getMousePos(canvas, e);
|
||||
var mouseX = mousePos.x;
|
||||
var mouseY = mousePos.y;
|
||||
}
|
||||
var cooldowned = false;
|
||||
if (mouseSize===1 && elements[currentElement].cooldown && !paused) {
|
||||
if (pixelTicks-lastPlace < elements[currentElement].cooldown) {
|
||||
return;
|
||||
}
|
||||
cooldowned = true;
|
||||
}
|
||||
lastPlace = pixelTicks;
|
||||
if (cooldowned && !startPos) {
|
||||
var coords = mouseRange(mouseX,mouseY);
|
||||
}
|
||||
else {
|
||||
startPos = startPos || lastPos
|
||||
var coords = lineCoords(startPos.x,startPos.y,mouseX,mouseY);
|
||||
}
|
||||
// if (!((cooldowned && startPos.x===lastPos.x && startPos.y===lastPos.y) || ((elements[currentElement].tool || elements[currentElement].category==="tools") && !elements[currentElement].canPlace))) {
|
||||
// }
|
||||
// else { var coords = mouseRange(mouseX,mouseY); }
|
||||
var element = elements[currentElement];
|
||||
var mixList = [];
|
||||
// For each x,y in coords
|
||||
var done = {};
|
||||
for (var i = 0; i < coords.length; i++) {
|
||||
var x = coords[i][0];
|
||||
var y = coords[i][1];
|
||||
if (!done[x]) {
|
||||
done[x] = {}
|
||||
}
|
||||
if (done[x][y]) { continue; }
|
||||
done[x][y] = true;
|
||||
|
||||
if (mode === "replace" && (!elements[currentElement].tool || elements[currentElement].canPlace)) {
|
||||
if (outOfBounds(x,y)) {
|
||||
continue;
|
||||
}
|
||||
// Remove pixel at position from currentPixels
|
||||
if (!isEmpty(x,y,true)) {
|
||||
if (!(currentElement === pixelMap[x][y].element && pixelMap[x][y].start === pixelTicks-1)) {
|
||||
deletePixel(x,y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentElement === "mix") {
|
||||
if (!isEmpty(x,y,true)) {
|
||||
var pixel = pixelMap[x][y];
|
||||
if (!(elements[pixel.element].movable !== true || elements[pixel.element].noMix === true) || shiftDown) {
|
||||
mixList.push(pixel);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (elements[currentElement].tool && !(elements[currentElement].canPlace && isEmpty(x,y))) {
|
||||
// run the tool function on the pixel
|
||||
if (!isEmpty(x,y,true)) {
|
||||
var pixel = pixelMap[x][y];
|
||||
// if the current element has an ignore property and the pixel's element is in the ignore property, don't do anything
|
||||
if (elements[currentElement].ignore && elements[currentElement].ignore.indexOf(pixel.element) !== -1) {
|
||||
continue;
|
||||
}
|
||||
elements[currentElement].tool(pixel);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (isEmpty(x, y)) {
|
||||
if (currentPixels.length < maxPixelCount) {
|
||||
createPixel(currentElement,x,y);
|
||||
if (pixelMap[x][y] && currentElement === pixelMap[x][y].element && (elements[currentElement].customColor || elements[currentElement].singleColor)) {
|
||||
pixelMap[x][y].color = pixelColorPick(pixelMap[x][y],currentColorMap[currentElement]);
|
||||
}
|
||||
if (currentElementProp) {
|
||||
for (var key in currentElementProp) {
|
||||
pixelMap[x][y][key] = currentElementProp[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!outOfBounds(x,y)) {
|
||||
if (elements[currentElement].extinguish) {
|
||||
var pixel = pixelMap[x][y];
|
||||
if (pixel.burning && elements[pixel.element].burning !== true) {
|
||||
delete pixel.burning;
|
||||
delete pixel.burnStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentElement === "mix") {
|
||||
// 1. repeat for each pixel in mixList
|
||||
// 2. choose 2 random pixels and swap their x and y
|
||||
// 3. remove pixel from mixList
|
||||
for (var i = 0; i < mixList.length; i++) {
|
||||
var pixel1 = mixList[Math.floor(Math.random()*mixList.length)];
|
||||
var pixel2 = mixList[Math.floor(Math.random()*mixList.length)];
|
||||
if (pixel1.element !== "head" && pixel2.element !== "head" && pixel1.element !== "body" && pixel2.element !== "body") {
|
||||
swapPixels(pixel1,pixel2);
|
||||
}
|
||||
else if (pixel1.element !== "head" && pixel2.element !== "head" && (pixel1.element === "body" || pixel2.element === "body")) {
|
||||
if (pixel1.element === "body") {
|
||||
if (!isEmpty(pixel1.x,pixel1.y-1, true)) {
|
||||
var headPixel1 = pixelMap[pixel1.x][pixel1.y-1]
|
||||
if (headPixel1.element === "head") {
|
||||
if (!isEmpty(pixel2.x,pixel2.y-1, true)) {
|
||||
var headPixel2 = pixelMap[pixel2.x][pixel2.y-1]
|
||||
if (headPixel2.element !== "body" && !(elements[headPixel2.element].movable !== true || elements[headPixel2.element].noMix === true)) {
|
||||
swapPixels(pixel1,pixel2);
|
||||
swapPixels(headPixel1,headPixel2);
|
||||
}
|
||||
}
|
||||
else if (isEmpty(pixel2.x,pixel2.y-1)) {
|
||||
swapPixels(pixel1,pixel2)
|
||||
tryMove(headPixel1, pixel1.x, pixel1.y-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pixel2.element === "body") {
|
||||
if (!isEmpty(pixel2.x,pixel2.y-1, true)) {
|
||||
var headPixel1 = pixelMap[pixel2.x][pixel2.y-1]
|
||||
if (headPixel1.element === "head") {
|
||||
if (!isEmpty(pixel1.x,pixel1.y-1, true)) {
|
||||
var headPixel2 = pixelMap[pixel1.x][pixel1.y-1]
|
||||
if (headPixel2.element !== "body" && !(elements[headPixel2.element].movable !== true || elements[headPixel2.element].noMix === true)) {
|
||||
swapPixels(pixel1,pixel2);
|
||||
swapPixels(headPixel1,headPixel2);
|
||||
}
|
||||
}
|
||||
else if (isEmpty(pixel1.x,pixel1.y-1)) {
|
||||
swapPixels(pixel1,pixel2);
|
||||
tryMove(headPixel1, pixel2.x,pixel2.y-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mixList.splice(mixList.indexOf(pixel1),1);
|
||||
mixList.splice(mixList.indexOf(pixel2),1);
|
||||
if (elements[pixel1.element].onMix) {
|
||||
elements[pixel1.element].onMix(pixel1,pixel2);
|
||||
}
|
||||
if (elements[pixel2.element].onMix) {
|
||||
elements[pixel2.element].onMix(pixel2,pixel1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pixelTick = function(pixel,custom=null) {
|
||||
if (pixel.start === pixelTicks) {return}
|
||||
btemp = {};
|
||||
if (elements[pixel.element] === undefined) {
|
||||
pixel.invalidElement = pixel.element;
|
||||
changePixel(pixel,"unknown");
|
||||
return;
|
||||
}
|
||||
var info = elements[pixel.element];
|
||||
btemp.info = info;
|
||||
btemp.pixel = pixel;
|
||||
if (custom) { var behavior = custom; }
|
||||
else if (pixel.charge && info.behaviorOn) { var behavior = info.behaviorOn; }
|
||||
else { var behavior = info.behavior; }
|
||||
if (pixel.flipX) { behavior = flipBehavior(behavior,"x"); }
|
||||
if (pixel.flipY) { behavior = flipBehavior(behavior,"y"); }
|
||||
if (pixel.r) { behavior = rotateBehavior(behavior,pixel.r); }
|
||||
var x = pixel.x;
|
||||
var y = pixel.y;
|
||||
var move1Spots = []; btemp.move1Spots = move1Spots;
|
||||
var move2Spots = []; btemp.move2Spots = move2Spots;
|
||||
var supportSpots = []; btemp.supportSpots = supportSpots;
|
||||
var swapSpots = []; btemp.swapSpots = swapSpots;
|
||||
btemp.mixSpots = [];
|
||||
btemp.move = true;
|
||||
// Parse behavior
|
||||
var height = behavior.length;
|
||||
for (var by = 0; by < behavior.length; by++) {
|
||||
var behaviorby = behavior[by];
|
||||
var width = behaviorby.length;
|
||||
for (var bx = 0; bx < behaviorby.length; bx++) {
|
||||
var b0 = behaviorby[bx];
|
||||
if (b0 === "XX") {continue}
|
||||
//if (b.includes(" OR ")) {
|
||||
// b = b.split(" OR ")[Math.floor(Math.random()*b.split(" OR ").length)];
|
||||
//}
|
||||
// Loop through b0.split(" AND ")
|
||||
if (b0.indexOf(" AND ") !== -1) { var andsplit = b0.split(" AND "); }
|
||||
else { var andsplit = [b0]; }
|
||||
for (var i = 0; i < andsplit.length; i++) {
|
||||
var b = andsplit[i];
|
||||
if (b.indexOf(":") !== -1) {
|
||||
var arg = b.split(":")[1].split(/[\:\%]/)[0];
|
||||
if (b.indexOf("%") === -1) {
|
||||
b = b.split(/[\:\%]/)[0];
|
||||
}
|
||||
}
|
||||
else { var arg = null;}
|
||||
btemp.arg = arg;
|
||||
// If b has "%" followed by a number in it, it's a chance to move
|
||||
if (b.indexOf("%") !== -1) {
|
||||
// Split the string at the "%" and use the second half as the chance (float)
|
||||
var chance = parseFloat(b.split("%")[1]);
|
||||
//console.log(b+": "+(Math.random()*100 < chance));
|
||||
b = b.split(/[\:\%]/)[0];
|
||||
}
|
||||
else { var chance = 100; }
|
||||
if (chance===100 || Math.random()*100 < chance) {
|
||||
var newCoords = behaviorCoords(x,y,bx,by,width,height);
|
||||
btemp.newCoords = newCoords;
|
||||
if (behaviorRules[b]) {
|
||||
behaviorRules[b]();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (btemp.deleted) {return;}
|
||||
if (supportSpots.length > 0) {
|
||||
var supportCount = 0;
|
||||
var allEmpty = true;
|
||||
for (var i = 0; i < supportSpots.length; i++) {
|
||||
var bx = supportSpots[i].x;
|
||||
var by = supportSpots[i].y;
|
||||
var arg = supportSpots[i].arg;
|
||||
if (!isEmpty(bx,by,true)) {
|
||||
if (info.ignore && info.ignore.indexOf(pixelMap[bx][by].element) !== -1) {continue;}
|
||||
if ((arg === null && !validDensitySwaps[info.state][elements[pixelMap[bx][by].element].state]) || pixelMap[bx][by].element == arg) {
|
||||
supportCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (supportCount == supportSpots.length) {
|
||||
btemp.move = false;
|
||||
}
|
||||
}
|
||||
|
||||
var moved = false;
|
||||
|
||||
if (swapSpots.length > 0) {
|
||||
var coords = swapSpots[Math.floor(Math.random()*swapSpots.length)];
|
||||
if (pixelMap[coords.x][coords.y] !== undefined) {
|
||||
swapPixels(pixel,pixelMap[coords.x][coords.y]);
|
||||
btemp.move = false;
|
||||
moved = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (btemp.mixSpots.length > 0) {
|
||||
for (var i = 0; i < btemp.mixSpots.length; i++) {
|
||||
var coord1 = choose(btemp.mixSpots);
|
||||
var coord2 = choose(btemp.mixSpots);
|
||||
var exists1 = !isEmpty(coord1.x,coord1.y,true);
|
||||
var exists2 = !isEmpty(coord2.x,coord2.y,true);
|
||||
if (isEmpty(coord1.x,coord1.y) && exists2) {
|
||||
var pixel1 = pixelMap[coord2.x][coord2.y]
|
||||
if (pixel1.element !== "head" && pixel1.element !== "body") {
|
||||
tryMove(pixel1,coord1.x,coord1.y);
|
||||
}
|
||||
else if (pixel1.element !== "head" && pixel1.element === "body") {
|
||||
if (!isEmpty(pixel1.x,pixel1.y-1, true)) {
|
||||
var headPixel1 = pixelMap[pixel1.x][pixel1.y-1]
|
||||
if (headPixel1.element === "head") {
|
||||
if (!isEmpty(coord1.x,coord1.y-1, true)) {
|
||||
var headPixel2 = pixelMap[coord1.x][coord1.y-1]
|
||||
if (headPixel2.element !== "body" && !(elements[headPixel2.element].movable !== true || elements[headPixel2.element].noMix === true)) {
|
||||
tryMove(pixel1,coord1.x,coord1.y);
|
||||
swapPixels(headPixel1,headPixel2);
|
||||
}
|
||||
}
|
||||
else if (isEmpty(coord1.x,coord1.y-1)) {
|
||||
tryMove(pixel1,coord1.x,coord1.y);
|
||||
tryMove(headPixel1, pixel1.x, pixel1.y-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (exists1 && isEmpty(coord2.x,coord2.y)) {
|
||||
var pixel1 = pixelMap[coord1.x][coord1.y]
|
||||
if (pixel1.element !== "head" && pixel1.element !== "body") {
|
||||
tryMove(pixel1,coord2.x,coord2.y);
|
||||
}
|
||||
else if (pixel1.element !== "head" && pixel1.element === "body") {
|
||||
if (!isEmpty(pixel1.x,pixel1.y-1, true)) {
|
||||
var headPixel1 = pixelMap[pixel1.x][pixel1.y-1]
|
||||
if (headPixel1.element === "head") {
|
||||
if (!isEmpty(coord2.x,coord2.y-1, true)) {
|
||||
var headPixel2 = pixelMap[coord2.x][coord2.y-1]
|
||||
if (headPixel2.element !== "body" && !(elements[headPixel2.element].movable !== true || elements[headPixel2.element].noMix === true)) {
|
||||
tryMove(pixel1,coord2.x,coord2.y);
|
||||
swapPixels(headPixel1,headPixel2);
|
||||
}
|
||||
}
|
||||
else if (isEmpty(coord2.x,coord2.y-1)) {
|
||||
tryMove(pixel1,coord2.x,coord2.y);
|
||||
tryMove(headPixel1, pixel1.x, pixel1.y-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (exists1 && exists2) {
|
||||
var pixel1 = pixelMap[coord1.x][coord1.y];
|
||||
var pixel2 = pixelMap[coord2.x][coord2.y];
|
||||
if (pixel1.element !== "head" && pixel2.element !== "head" && pixel1.element !== "body" && pixel2.element !== "body") {
|
||||
swapPixels(pixel1,pixel2);
|
||||
}
|
||||
else if (pixel1.element !== "head" && pixel2.element !== "head" && (pixel1.element === "body" || pixel2.element === "body")) {
|
||||
if (pixel1.element === "body") {
|
||||
if (!isEmpty(pixel1.x,pixel1.y-1, true)) {
|
||||
var headPixel1 = pixelMap[pixel1.x][pixel1.y-1]
|
||||
if (headPixel1.element === "head") {
|
||||
if (!isEmpty(pixel2.x,pixel2.y-1, true)) {
|
||||
var headPixel2 = pixelMap[pixel2.x][pixel2.y-1]
|
||||
if (headPixel2.element !== "body" && !(elements[headPixel2.element].movable !== true || elements[headPixel2.element].noMix === true)) {
|
||||
swapPixels(pixel1,pixel2);
|
||||
swapPixels(headPixel1,headPixel2);
|
||||
}
|
||||
}
|
||||
else if (isEmpty(pixel2.x,pixel2.y-1)) {
|
||||
swapPixels(pixel1,pixel2)
|
||||
tryMove(headPixel1, pixel1.x, pixel1.y-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pixel2.element === "body") {
|
||||
if (!isEmpty(pixel2.x,pixel2.y-1, true)) {
|
||||
var headPixel1 = pixelMap[pixel2.x][pixel2.y-1]
|
||||
if (headPixel1.element === "head") {
|
||||
if (!isEmpty(pixel1.x,pixel1.y-1, true)) {
|
||||
var headPixel2 = pixelMap[pixel1.x][pixel1.y-1]
|
||||
if (headPixel2.element !== "body" && !(elements[headPixel2.element].movable !== true || elements[headPixel2.element].noMix === true)) {
|
||||
swapPixels(pixel1,pixel2);
|
||||
swapPixels(headPixel1,headPixel2);
|
||||
}
|
||||
}
|
||||
else if (isEmpty(pixel1.x,pixel1.y-1)) {
|
||||
swapPixels(pixel1,pixel2);
|
||||
tryMove(headPixel1, pixel2.x,pixel2.y-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (elements[pixel1.element].onMix) {
|
||||
elements[pixel1.element].onMix(pixel1,pixel2);
|
||||
}
|
||||
if (elements[pixel2.element].onMix) {
|
||||
elements[pixel2.element].onMix(pixel2,pixel1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (btemp.sticking) {
|
||||
btemp.move = false;
|
||||
}
|
||||
|
||||
// Move First Priority
|
||||
if (btemp.move) {
|
||||
if (move1Spots.length > 0) {
|
||||
// While move1Spots is not empty
|
||||
while (move1Spots.length > 0) {
|
||||
// coords = random item of move1Spots
|
||||
var j = Math.floor(Math.random()*move1Spots.length);
|
||||
var coords = move1Spots[j];
|
||||
var nx = coords.x;
|
||||
var ny = coords.y;
|
||||
moved = tryMove(pixel,nx,ny,btemp.leaveBehind1 || btemp.leaveBehind);
|
||||
if (moved) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// remove coords from move1Spots
|
||||
move1Spots.splice(j,1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
// Move Second Priority
|
||||
if (!moved && move2Spots.length > 0) {
|
||||
// While move2Spots is not empty
|
||||
while (move2Spots.length > 0) {
|
||||
// coords = random item of move2Spots
|
||||
var j = Math.floor(Math.random()*move2Spots.length);
|
||||
var coords = move2Spots[j];
|
||||
var nx = coords.x;
|
||||
var ny = coords.y;
|
||||
moved = tryMove(pixel,nx,ny,btemp.leaveBehind2 || btemp.leaveBehind);
|
||||
if (moved) {
|
||||
if (btemp.C2 && elements[btemp.C2]) {
|
||||
changePixel(pixel,btemp.C2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// remove coords from move2Spots
|
||||
move2Spots.splice(j,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
doAirDensity(pixel);
|
||||
|
||||
|
||||
// Change tempearture if needed (unused)
|
||||
/*if (info.tempChange != undefined) {
|
||||
pixel.temp += info.tempChange;
|
||||
pixelTempCheck(pixel);
|
||||
}*/
|
||||
|
||||
// Burning
|
||||
doBurning(pixel);
|
||||
|
||||
// Heat Transfer
|
||||
if (info.insulate !== true) {
|
||||
doHeat(pixel);
|
||||
}
|
||||
|
||||
// Electricity Transfer
|
||||
doElectricity(pixel);
|
||||
|
||||
// Staining
|
||||
if (info.stain) {
|
||||
doStaining(pixel);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue