var modName = "mods/ray_cloner.js"; var libraryMod = "mods/code_library.js"; var propMod = "mods/prop.js"; var variablesMod = "mods/prop and prompt variables.js"; if(enabledMods.includes(libraryMod) && enabledMods.includes(propMod) && enabledMods.includes(variablesMod)) { function placeRegularlySpacedPixels(element,startX,startY,xSpacing,ySpacing,overwrite=false,stopAt=null,spawnTemp=null,limit=1000) { if(element.includes(",")) { element = element.split(",") }; var newElement = element; if(isNaN(xSpacing) || isNaN(ySpacing)) { throw new Error("Missing xSpacing or ySpacing"); }; if(xSpacing == 0 && ySpacing == 0) { //pixel.color = convertColorFormats("#5F5F5F","rgb"); return false; }; if(outOfBounds(startX,startY) || (!overwrite && !isEmpty(startX,startY,false))) { return false; }; var posX = startX; var posY = startY; var pixelsPlaced = 0; //console.log(stopAt); //var tries = 0; while(!outOfBounds(posX,posY)) { if(newElement instanceof Array) { newElement = newElement[Math.floor(Math.random() * newElement.length)] }; if(!elements[newElement]) { //pixel.color = convertColorFormats("#FF5F5F","rgb"); console.error(`Nonexistent element ${newElement}`); return false; }; if(isEmpty(posX,posY,true)) { createPixel(newElement,posX,posY); if(spawnTemp !== null) { pixelMap[posX][posY].temp = spawnTemp }; pixelsPlaced++; } else { if(outOfBounds(posX,posY)) { break; } else { if(!isEmpty(posX,posY,true)) { if(stopAt) { var otherElement = pixelMap[posX][posY].element; if(stopAt instanceof Array) { if(pixel.stopAt.includes(otherElement)) { break }; } else { if(otherElement == pixel.stopAt) { break }; }; }; if(overwrite) { changePixel(pixelMap[posX][posY],newElement) if(spawnTemp !== null) { pixelMap[posX][posY].temp = spawnTemp; }; pixelsPlaced++ } else { break }; }; }; }; posX += xSpacing; posY += ySpacing; if(limit !== null && pixelsPlaced >= limit) { return true; }; }; return true; }; elements.ray_cloner = { properties: { xSpacing: 0, ySpacing: 0, overwrite: false, stopAt: null, spawnAtPixelTemp: false, maxPixels: 1000, }, tick: function(pixel) { storeFirstTouchingElement(pixel,"clone",true,true); if(pixel.clone && pixel.charge) { placeRegularlySpacedPixels(pixel.clone,pixel.x+pixel.xSpacing,pixel.y+pixel.ySpacing,pixel.xSpacing,pixel.ySpacing,pixel.overwrite,pixel.stopAt,pixel.spawnAtPixelTemp ? pixel.temp : null,pixel.maxPixels); pixel.charge = 0 }; }, conduct: 1, category: "machines", state: "solid", density: 3000, hardness: 0.8, color: "#FFFF7F", desc: `clone: Which element to place. Cannot be an array or comma-separated string, and will be chosen from the first pixel to touch it.
xSpacing and ySpacing: Horizontal and vertical spacing between x pixels. Note that blocking is only checked at these intervals. An xSpacing of 0 with a ySpacing of 1 would give a straight line going down; xS1 and yS0 would give a line to the right.
overwrite (default false): Whether to replace pixels the line goes into.
stopAt (default null): Elements the line to stop at if it hits. Also applies to overwrite, and has no effect if set to null. Can be a string or an array.
spawnAtPixelTemp (default false): Whether to place new pixels at the same temperature as this pixel.
maxPixels (default 1000): Maximum amount of pixels/changes (if xSpacing and ySpacing are both less than 2, this corresponds to the pixel length of the line). prop.js is highly recommended to set pixel properties`, }; } else { if(!enabledMods.includes(libraryMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod) }; if(!enabledMods.includes(propMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,propMod) }; if(!enabledMods.includes(variablesMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,variablesMod) }; localStorage.setItem("enabledMods", JSON.stringify(enabledMods)); alert(`The "${libraryMod}", "${propMod}", and "${variablesMod}" mods are all required and have been automatically inserted (reload for this to take effect).`); };