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); } }