diff --git a/mods/portal.js b/mods/portal.js index 36a206e5..aa9caaef 100644 --- a/mods/portal.js +++ b/mods/portal.js @@ -1,66 +1,120 @@ -function includesArray(parentArray, testArray) { - for (let i = 0; i < parentArray.length; i++) { - if (parentArray[i].every(function(value, index) { return value === testArray[index]})) { - return true; - } - } - return false; -} +var modName = "mods/portal.js"; +var onTryMoveIntoMod = "mods/onTryMoveInto.js"; +var libraryMod = "mods/code_library.js"; -elements.portal_in = { - color: "#ee7f00", - tick: function(pixel) { - if(!pixel.portalArray) { pixel.portalArray = [] } - if(!Array.isArray(pixel.portalArray)) { pixel.portalArray = [] } - for (var i = 1; i < width; i++) { - for (var j = 1; j < height; j++) { - if (!isEmpty(i,j)) { - if(pixelMap[i][j].element == "portal_out") { - if(!includesArray(pixel.portalArray,[i,j])) { - pixel.portalArray.push([i,j]) - } - } - } - if (isEmpty(i,j)) { - if(includesArray(pixel.portalArray,[i,j])) { - pixel.portalArray = pixel.portalArray.filter(dat => !includesArray(pixel.portalArray,[i,j])) +if(enabledMods.includes(onTryMoveIntoMod) && enabledMods.includes(libraryMod)) { + //https://stackoverflow.com/a/60922255 + if(!enabledMods.includes("mods/mobs.js")) { + headBodyObject = { + "head": "body", + }; + }; - } - } - } - } - if(pixel.portalArray.length > 0) { - randomDestination = pixel.portalArray[Math.floor((Math.random() * pixel.portalArray.length))] - if(!isEmpty(pixel.x-1,pixel.y) && !outOfBounds(pixel.x-1,pixel.y)) { - if(pixelMap[pixel.x-1][pixel.y].element != pixel.element) { - tryMove(pixelMap[pixel.x-1][pixel.y],(randomDestination[0] + 1),(randomDestination[1])) - } - } - if(!isEmpty(pixel.x+1,pixel.y) && !outOfBounds(pixel.x+1,pixel.y)) { - if(pixelMap[pixel.x+1][pixel.y].element != pixel.element) { - tryMove(pixelMap[pixel.x+1][pixel.y],(randomDestination[0] - 1),(randomDestination[1])) - } - } - if(!isEmpty(pixel.x,pixel.y-1) && !outOfBounds(pixel.x,pixel.y-1)) { - if(pixelMap[pixel.x][pixel.y-1].element != pixel.element) { - tryMove(pixelMap[pixel.x][pixel.y-1],(randomDestination[0]),(randomDestination[1] + 1)) - } - } - if(!isEmpty(pixel.x,pixel.y+1) && !outOfBounds(pixel.x,pixel.y+1)) { - if(pixelMap[pixel.x][pixel.y+1].element != pixel.element) { - tryMove(pixelMap[pixel.x][pixel.y+1],(randomDestination[0]),(randomDestination[1] - 1)) - } - } - } + elements.portal_in = { + color: "#ee7f00", + properties: { + _channel: 0, + _correspondingPortals: null, + }, + insulate: true, + onTryMoveInto: function(pixel,otherPixel) { + if(pixel._correspondingPortals == null) { + return; + }; + if(pixel._correspondingPortals.length <= 0) { + return; + }; + + var portal = randomChoice(pixel._correspondingPortals); + + var offset = {x: pixel.x - otherPixel.x, y: pixel.y - otherPixel.y}; //teleport destination's offset, inverted by subtraction + + var destination = {x: portal.x + offset.x, y: portal.y + offset.y}; + + var otherElement = otherPixel.element; + var isHead = (typeof(headBodyObject[otherElement]) !== "undefined"); + var isBody = (typeof(getKeyByValue(headBodyObject,otherElement)) !== "undefined"); + var isBipartite = xor(isHead,isBody); //a head being its own body will break the code + + if(isBipartite) { + if(isHead) { + var dead = otherPixel.dead; + var body = pixelMap[otherPixel.x][otherPixel.y+1]; + if(body == undefined) { body = null }; + if(!dead && (body !== null)) { + if(offset.y == -1) { + offset.y--; + destination.y--; + }; + var headSpotIsEmpty = isEmpty(destination.x,destination.y,false); + var bodySpotIsEmpty = isEmpty(destination.x,destination.y+1,false); + if(headSpotIsEmpty && bodySpotIsEmpty) { + tryMove(otherPixel,destination.x,destination.y); + tryMove(body,destination.x,destination.y+1); + }; + } else { + tryMove(otherPixel,destination.x,destination.y); + }; + } else if(isBody) { + var dead = otherPixel.dead; + var head = pixelMap[otherPixel.x][otherPixel.y-1]; + if(head == undefined) { head = null }; + if(!dead && (head !== null)) { + if(offset.y == 1) { + offset.y++; + destination.y++; + }; + var headSpotIsEmpty = isEmpty(destination.x,destination.y-1,false); + var bodySpotIsEmpty = isEmpty(destination.x,destination.y,false); + if(headSpotIsEmpty && bodySpotIsEmpty) { + tryMove(head,destination.x,destination.y-1); + tryMove(otherPixel,destination.x,destination.y); + }; + } else { + tryMove(otherPixel,destination.x,destination.y); + }; + }; + } else { + tryMove(otherPixel,destination.x,destination.y); + }; + }, + tick: function(pixel) { + pixel._channel = Math.floor(pixel.temp / 100); + + pixel._correspondingPortals = currentPixels.filter(function(pixelToCheck) { + return ( + pixelToCheck.element == "portal_out" && + pixelToCheck._channel == pixelChannel + ); + },pixelChannel=pixel._channel); + + for(i = 0; i < pixel._correspondingPortals.length; i++) { + pixel._correspondingPortals[i] = {x: pixel._correspondingPortals[i].x, y: pixel._correspondingPortals[i].y}; + }; + + //pixel.tempdebug = JSON.stringify(pixel._correspondingPortals); + }, + category: "machines", + state: "solid", }, - category: "machines", - state: "solid", - portalArray: [], -}, -elements.portal_out = { - color: "#2222ee", - behavior: behaviors.WALL, - category: "machines", - state: "solid", -} + elements.portal_out = { + color: "#2222ee", + properties: { + channel: 0 + }, + insulate: true, + tick: function(pixel) { + pixel._channel = Math.floor(pixel.temp / 100); + }, + behavior: behaviors.WALL, + category: "machines", + state: "solid", + insulate: true, + } +} else { + if(!enabledMods.includes(libraryMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod) }; + if(!enabledMods.includes(onTryMoveIntoMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,onTryMoveIntoMod) }; + localStorage.setItem("enabledMods", JSON.stringify(enabledMods)); + alert(`The "${libraryMod}" and "${onTryMoveIntoMod}" mods are all required; any missing mods in this list have been automatically inserted (reload for this to take effect).`) +};