From 2d14411305c9acf981a3041f6927937f1ba50f49 Mon Sep 17 00:00:00 2001 From: Nekonico <163950752+DBNekonico@users.noreply.github.com> Date: Thu, 2 Oct 2025 18:45:16 -0700 Subject: [PATCH 1/5] keycard update --- mods/scp.js | 528 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 489 insertions(+), 39 deletions(-) diff --git a/mods/scp.js b/mods/scp.js index 28b0118a..68257180 100644 --- a/mods/scp.js +++ b/mods/scp.js @@ -39,6 +39,14 @@ window.addEventListener("load", () => { document.getElementById("elementButton-REDACTED")?.remove() }) +async function _scpAskPrompt(message, defaultValue = "") { + return new Promise(resolve => { + promptInput(message, (result) => { + resolve(result); + }, "Awaiting credentials...", defaultValue); + }) +} + hex_is_light = function(color) { hex = color.replace('#', ''); c_r = parseInt(hex.substring(0, 0 + 2), 16); @@ -65,6 +73,47 @@ elements.human.reactions.scp_229 = { attr1:{panic:5} } elements.human.reactions.scp_999 = { attr1:{panic:0} } elements.human.reactions.black_acid = { attr1:{panic:1} } +if (!elements.water.reactions) { elements.water.reactions = {}; } +elements.water.reactions.access_door = { elem1:null, elem2:"rust", chance:0.000125 } + +if (!elements.body.reactions) { elements.body.reactions = {}; } +elements.body.reactions.level_0 = { chance:0.3, func:function(pixel1,pixel2){ + if (!pixel1.level || pixel1.level > pixel2.level) { + pixel1.level = pixel2.level + deletePixel(pixel2.x,pixel2.y) + } +} }, +elements.body.reactions.level_1 = { chance:0.5, func:function(pixel1,pixel2){ + if (!pixel1.level || pixel1.level > pixel2.level) { + pixel1.level = pixel2.level + deletePixel(pixel2.x,pixel2.y) + } +} }, +elements.body.reactions.level_2 = { chance:0.5, func:function(pixel1,pixel2){ + if (!pixel1.level || pixel1.level > pixel2.level) { + pixel1.level = pixel2.level + deletePixel(pixel2.x,pixel2.y) + } +} }, +elements.body.reactions.level_3 = { chance:0.5, func:function(pixel1,pixel2){ + if (!pixel1.level || pixel1.level > pixel2.level) { + pixel1.level = pixel2.level + deletePixel(pixel2.x,pixel2.y) + } +} }, +elements.body.reactions.level_4 = { chance:0.5, func:function(pixel1,pixel2){ + if (!pixel1.level || pixel1.level > pixel2.level) { + pixel1.level = pixel2.level + deletePixel(pixel2.x,pixel2.y) + } +} }, +elements.body.reactions.level_5 = { chance:0.5, func:function(pixel1,pixel2){ + if (!pixel1.level || pixel1.level > pixel2.level) { + pixel1.level = pixel2.level + deletePixel(pixel2.x,pixel2.y) + } +} }, + hyperCoords = [ [0,1], [0,1], @@ -102,12 +151,289 @@ elements.metanarrative_ontokinetic_hume_stabilizing_anomaly_neutralizing_all_pow hidden: true, } +currentLevel = 0 +elements.keycard_terminal = { + color: "#C6B589", + onSelect: async function() { + currentLevel = await _scpAskPrompt("Please input the desired level requirement of this terminal as a number 0 through 5.", (currentLevel||undefined)) + }, + onPlace: function(pixel) { + if (!pixel.levelReq){ + pixel.levelReq = currentLevel; + pixel.clone = pixel.levelReq; + } + }, + tick: function(pixel) { + if (!pixel.levelReq){ + pixel.levelReq = currentLevel; + pixel.clone = pixel.levelReq; + } + if (!pixel.clone){ + pixel.clone = pixel.levelReq; + } + if (!isEmpty(pixel.x, pixel.y-1, true)){ + if (pixel.levelReq && elements[pixelMap[pixel.x][pixel.y-1].element].level < pixel.levelReq) {} + else if (pixelMap[pixel.x][pixel.y-1].level >= pixel.levelReq && (pixelMap[pixel.x][pixel.y-1].element == "body" || pixelMap[pixel.x][pixel.y-1].element == "bead" || elements[pixelMap[pixel.x][pixel.y-1].element].keycard == true)|| pixelMap[pixel.x][pixel.y-1].on) { + pixel.on = true; + var coordsToShock = [ + [pixel.x, pixel.y+1], + [pixel.x+1, pixel.y], + [pixel.x-1, pixel.y], + ] + for (var i = 0; i < coordsToShock.length; i++) { + var x = coordsToShock[i][0]; + var y = coordsToShock[i][1]; + if (!isEmpty(x,y,true)) { + var newpixel = pixelMap[x][y]; + if (elements[newpixel.element].conduct) { + newpixel.charge = 1; + } + } + } + } + } + else if (pixel.on) { + pixel.on = false; + } + doDefaults(pixel); + }, + category: "scp", + state: "solid", + density: 6394.4 +} + +elements.access_door = { + color: "#515151", + onSelect: async function() { + currentLevel = await _scpAskPrompt("Please input the desired level requirement of this door as a number 0 through 5.", (currentLevel||undefined)) + }, + onPlace: function(pixel) { + if (!pixel.levelReq){ + pixel.levelReq = currentLevel; + pixel.clone = pixel.levelReq; + } + }, + tick: function(pixel) { + if (pixel.level){ + pixel.levelReq = pixel.level; + pixel.clone = pixel.level; + delete pixel.level + } + else if (!pixel.levelReq){ + pixel.levelReq = currentLevel; + pixel.clone = pixel.levelReq; + } + if (!pixel.clone){ + pixel.clone = pixel.levelReq; + } + if (!isEmpty(pixel.x-1, pixel.y, true) && !outOfBounds(pixel.x-1, pixel.y) && Math.random() > 0.9){ + let neighbor = pixelMap[pixel.x-1][pixel.y] + if (pixel.levelReq && elements[neighbor.element].level < pixel.levelReq) {} + else if (neighbor.level >= pixel.levelReq && (neighbor.element == "body" || neighbor.element == "body_1000" || neighbor.element == "body_008" || neighbor.element == "body_1015" || neighbor.element == "body_035" || neighbor.element == "body_012_1")) { + if (neighbor.dir == 1 && !isEmpty(neighbor.x,neighbor.y-1) && !outOfBounds(neighbor.x,neighbor.y-1)) { + if (isEmpty(pixel.x+1,pixel.y) && isEmpty(pixel.x+1,pixel.y-1)) { + if (tryMove(pixelMap[neighbor.x][neighbor.y-1],pixel.x+1,pixel.y-1)) { + movePixel(neighbor,pixel.x+1,pixel.y) + } + } + else if (isEmpty(pixel.x+1,pixel.y-1) && isEmpty(pixel.x+1,pixel.y-2)) { + if (tryMove(pixelMap[neighbor.x][neighbor.y-1],pixel.x+1,pixel.y-2)) { + movePixel(neighbor,pixel.x+1,pixel.y-1) + } + } + else if (isEmpty(pixel.x+1,pixel.y+1) && isEmpty(pixel.x+1,pixel.y)) { + if (tryMove(pixelMap[neighbor.x][neighbor.y-1],pixel.x+1,pixel.y)) { + movePixel(neighbor,pixel.x+1,pixel.y+1) + } + } + else if (!isEmpty(pixel.x+1,pixel.y) && !isEmpty(pixel.x+1,pixel.y-1) && isEmpty(pixel.x+2,pixel.y+1) && isEmpty(pixel.x+2,pixel.y)) { + let doorB = pixelMap[pixel.x+1][pixel.y] + let doorH = pixelMap[pixel.x+1][pixel.y-1] + if (doorB.levelReq <= pixel.levelReq && doorH.levelReq <= pixel.levelReq) { + if (tryMove(pixelMap[neighbor.x][neighbor.y-1],pixel.x+2,pixel.y-1)) { + movePixel(neighbor,pixel.x+2,pixel.y) + } + } + } + } + } + } + else if (!isEmpty(pixel.x+1, pixel.y, true) && !outOfBounds(pixel.x+1, pixel.y) && Math.random() > 0.9){ + let neighbor = pixelMap[pixel.x+1][pixel.y] + if (pixel.levelReq && elements[neighbor.element].level < pixel.levelReq) {} + else if (neighbor.level >= pixel.levelReq && (neighbor.element == "body" || neighbor.element == "body_1000" || neighbor.element == "body_008" || neighbor.element == "body_1015" || neighbor.element == "body_035" || neighbor.element == "body_012_1")) { + if (neighbor.dir == -1 && !isEmpty(neighbor.x,neighbor.y-1) && !outOfBounds(neighbor.x,neighbor.y-1)) { + if (isEmpty(pixel.x-1,pixel.y) && isEmpty(pixel.x-1,pixel.y-1)) { + if (tryMove(pixelMap[neighbor.x][neighbor.y-1],pixel.x-1,pixel.y-1)) { + movePixel(neighbor,pixel.x-1,pixel.y) + } + } + else if (isEmpty(pixel.x-1,pixel.y-1) && isEmpty(pixel.x-1,pixel.y-2)) { + if (tryMove(pixelMap[neighbor.x][neighbor.y-1],pixel.x-1,pixel.y-2)) { + movePixel(neighbor,pixel.x-1,pixel.y-1) + } + } + else if (isEmpty(pixel.x-1,pixel.y+1) && isEmpty(pixel.x-1,pixel.y)) { + if (tryMove(pixelMap[neighbor.x][neighbor.y-1],pixel.x-1,pixel.y)) { + movePixel(neighbor,pixel.x-1,pixel.y+1) + } + } + else if (!isEmpty(pixel.x-1,pixel.y) && !isEmpty(pixel.x-1,pixel.y-1)) { + let doorB = pixelMap[pixel.x-1][pixel.y] + let doorH = pixelMap[pixel.x-1][pixel.y-1] + if (doorB.levelReq <= pixel.levelReq && doorH.levelReq <= pixel.levelReq && isEmpty(pixel.x-2,pixel.y+1) && isEmpty(pixel.x-2,pixel.y)) { + if (tryMove(pixelMap[neighbor.x][neighbor.y-1],pixel.x-2,pixel.y-1)) { + movePixel(neighbor,pixel.x-2,pixel.y) + } + } + } + } + } + } + tryMove(pixel, pixel.x, pixel.y+1); + doDefaults(pixel); + }, + grain: 0.5, + behavior: behaviors.WALL, + tempHigh: 1200, + stateHigh: "molten_galvanized_steel", + stateHighColorMultiplier: 0.86, + conduct: 0.475, + hardness: 0.8, + breakInto: "galvanized_steel", + breakIntoColorMultiplier: [1.1,1,0.86], + category: "scp", + state: "solid", + density: 7850, +} + +elements.level_0 = { + color: ["#635957","#AB9D9C","#D3CCCC"], + name: "Level 0 Keycard", + behavior: behaviors.STURDYPOWDER, + keycard: true, + tick: function(pixel) { + if (!pixel.level){ + pixel.level = 0; + } + doDefaults(pixel); + }, + category: "scp", + tempHigh: 185, + stateHigh: "molten_plastic", + burn: 10, + burnTime: 400, + burnInto: "dioxin", + state: "solid", + density: 1052, +} +elements.level_1 = { + color: ["#8C7D0D","#FDE507","#FCF081"], + name: "Level 1 Keycard", + behavior: behaviors.STURDYPOWDER, + keycard: true, + tick: function(pixel) { + if (!pixel.level){ + pixel.level = 1; + } + doDefaults(pixel); + }, + category: "scp", + tempHigh: 185, + stateHigh: "molten_plastic", + burn: 10, + burnTime: 400, + burnInto: "dioxin", + state: "solid", + density: 1052, +} +elements.level_2 = { + color: ["#8C710B","#FDCC03","#FCE47F"], + name: "Level 2 Keycard", + behavior: behaviors.STURDYPOWDER, + keycard: true, + tick: function(pixel) { + if (!pixel.level){ + pixel.level = 2; + } + doDefaults(pixel); + }, + category: "scp", + tempHigh: 190, + stateHigh: ["molten_plastic","molten_plastic","glue"], + burn: 10, + burnTime: 400, + burnInto: "dioxin", + state: "solid", + density: 1052, +} +elements.level_3 = { + color: ["#885C28","#F6A33D","#F9CF9C"], + name: "Level 3 Keycard", + behavior: behaviors.STURDYPOWDER, + keycard: true, + tick: function(pixel) { + if (!pixel.level){ + pixel.level = 3; + } + doDefaults(pixel); + }, + category: "scp", + tempHigh: 190, + stateHigh: ["molten_plastic","molten_plastic","molten_plastic","glue"], + burn: 5, + burnTime: 400, + burnInto: "dioxin", + state: "solid", + density: 1057, +} +elements.level_4 = { + color: ["#87371D","#F35828","#F7AA92"], + name: "Level 4 Keycard", + behavior: behaviors.STURDYPOWDER, + keycard: true, + tick: function(pixel) { + if (!pixel.level){ + pixel.level = 4; + } + doDefaults(pixel); + }, + category: "scp", + tempHigh: 660.3, + density: 2600, + conduct: 0.73, + hardness: 0.05, + breakInto: "metal_scrap", + stateHigh:"molten_aluminum", + superconductAt: -271.95, + state: "solid", +} +elements.level_5 = { + color: ["#831924","#EB1C36","#F38C99"], + name: "Level 5 Keycard", + behavior: behaviors.STURDYPOWDER, + keycard: true, + tick: function(pixel) { + if (!pixel.level){ + pixel.level = 5; + } + doDefaults(pixel); + }, + category: "scp", + tempHigh: 927, + density: 8330, + conduct: 0.52, + hardness: 0.275, + stateHigh: "molten_tungsten", + state: "solid", +} + elements.site_nuke = { color: "#815E2B", behavior: behaviors.WALL, behaviorOn: [ "XX|XX|XX", - "XX|EX:250>molten_glass,molten_glass,plasma,plasma,plasma,plasma,plasma,plasma,plasma,radiation,radiation,radiation,rad_steam,electric,electric,electric|XX", + "XX|EX:300>plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,radiation,radiation,radiation,rad_steam,electric,electric,electric|XX", "M2|M1|M2", ], conduct: 1, @@ -185,6 +511,7 @@ elements.scientist = { if (isEmpty(pixel.x, pixel.y+1)) { createPixel("body", pixel.x, pixel.y+1); pixelMap[pixel.x][pixel.y+1].color = pixelColorPick(pixelMap[pixel.x][pixel.y+1], elements.scientist.buttonColor) + pixelMap[pixel.x][pixel.y+1].level = 2 var color = pixel.color; changePixel(pixel,"head"); pixel.color = color; @@ -194,6 +521,7 @@ elements.scientist = { pixelMap[pixel.x][pixel.y-1].color = pixel.color; changePixel(pixel,"body"); pixel.color = pixelColorPick(pixel, elements.scientist.buttonColor); + pixel.level = 2 } else { deletePixel(pixel.x, pixel.y); @@ -227,7 +555,7 @@ elements.guard = { // color: ["#f5eac6","#d4c594","#a89160","#7a5733","#523018","#361e0e"], color: ["#f3e7db","#f7ead0","#eadaba","#d7bd96","#a07e56","#825c43","#604134","#3a312a"], buttonColor: ["#848692","#2B2A30","#515159","#3A393F"], - name: "Security Guard", + name: "Security Officer", category: "scp", properties: { dead: false, @@ -238,6 +566,7 @@ elements.guard = { if (isEmpty(pixel.x, pixel.y+1)) { createPixel("body", pixel.x, pixel.y+1); pixelMap[pixel.x][pixel.y+1].color = pixelColorPick(pixelMap[pixel.x][pixel.y+1], elements.guard.buttonColor) + pixelMap[pixel.x][pixel.y+1].level = 2 var color = pixel.color; changePixel(pixel,"head"); pixel.color = color; @@ -247,6 +576,62 @@ elements.guard = { pixelMap[pixel.x][pixel.y-1].color = pixel.color; changePixel(pixel,"body"); pixel.color = pixelColorPick(pixel, elements.guard.buttonColor); + pixel.level = 2 + } + else { + deletePixel(pixel.x, pixel.y); + } + }, + reactions: { + "fire": { attr1:{panic:5} }, + "plasma": { attr1:{panic:5} }, + "cold_fire": { attr1:{panic:5} }, + "electric": { attr1:{panic:5} }, + "blood": { attr1:{panic:1} }, + "infection": { attr1:{panic:2} }, + "cancer": { attr1:{panic:3} }, + "plague": { attr1:{panic:5} }, + "radiation": { attr1:{panic:5} }, + "tnt": { attr1:{panic:5} }, + "dynamite": { attr1:{panic:5} }, + "c4": { attr1:{panic:5} }, + "grenade": { attr1:{panic:5} }, + "gunpowder": { attr1:{panic:5} }, + "acid": { attr1:{panic:5} }, + "acid_gas": { attr1:{panic:5} }, + "stench": { attr1:{panic:2} } + }, + related: ["body","head"], + cooldown: defaultCooldown, + forceSaveColor: true, +} + +elements.director = { + // color: ["#f5eac6","#d4c594","#a89160","#7a5733","#523018","#361e0e"], + color: ["#f3e7db","#f7ead0","#eadaba","#d7bd96","#a07e56","#825c43","#604134","#3a312a"], + buttonColor: ["#2B2A30","#848692","#2B2A30","#515159","#919092","#069469","#047e99","#7f5fb0","#069469","#047e99","#7f5fb0","#EDEEF7","#D9D9E7","#F8F7FC","#C6C8DC","#D0DCF1"], + name: "Site Director", + category: "scp", + properties: { + dead: false, + dir: 1, + panic: 0 + }, + onPlace: function(pixel) { + if (isEmpty(pixel.x, pixel.y+1)) { + createPixel("body", pixel.x, pixel.y+1); + pixelMap[pixel.x][pixel.y+1].color = pixelColorPick(pixelMap[pixel.x][pixel.y+1], elements.director.buttonColor) + pixelMap[pixel.x][pixel.y+1].level = 4 + var color = pixel.color; + changePixel(pixel,"head"); + pixel.color = color; + } + 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"); + pixel.color = pixelColorPick(pixel, elements.director.buttonColor); + pixel.level = 4 } else { deletePixel(pixel.x, pixel.y); @@ -1130,6 +1515,20 @@ elements.red_water = { "bird":{elem2:"scp_009_meat", chance:0.015}, "frog":{elem2:"scp_009_meat", chance:0.015}, "tadpole":{elem2:"scp_009_meat", chance:0.015}, + "iron": { elem1:null, elem2:"rust", chance:0.025 }, + "steel": { elem1:null, elem2:"rust", chance:0.02 }, + "galvanized_steel": { elem1:null, elem2:"rust", chance:0.00025 }, + "access_door": { elem1:null, elem2:"rust", chance:0.00025 }, + "aluminum": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.0025 }, + "zinc": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.015 }, + "steel": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.0125 }, + "iron": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.0125 }, + "tin": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.01 }, + "brass": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.001 }, + "bronze": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.001 }, + "copper": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.0075 }, + "silver": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.0075 }, + "gold": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.0075 } }, tempLow: -100, stateLow: "red_steam", @@ -1981,11 +2380,6 @@ elements.head_035 = { name: "SCP-035-1", color: ["#f7ead0","#faf9f6","#e9e6db"], category: "life", - behavior: [ - "CR:black_acid%0.01|CR:black_acid%0.05|CR:black_acid%0.01", - "CR:black_acid%0.05|XX|CR:black_acid%0.05", - "CR:black_acid%0.01|CR:black_acid%0.05|CR:black_acid%0.01", - ], hidden: true, density: 1080, state: "solid", @@ -2026,7 +2420,10 @@ elements.head_035 = { doHeat(pixel); doBurning(pixel); doElectricity(pixel); - if (pixel.dead) { + if (Math.random() < 0.0125) { + releaseElement(pixel,"black_acid",4,true) + } + if (pixel.dead || (pixel.start+1000) , pixelTicks && Math.random() > 0.95) { // Turn into rotten_meat if pixelTicks-dead > 500 if (pixelTicks-pixel.dead > 200 && Math.random() < 0.1) { changePixel(pixel,"rotten_meat"); @@ -2772,7 +3169,7 @@ elements.scp_063 = { "DL|XX|DL", "M2%80 AND DL|M1 AND DL|M2%80 AND DL", ], - ignore: ["scp_063","head_049","body_049","head_096","body_096","head_049_1","body_049_1","head_008_1","body_008_1","head_012_1","body_012_1","scp_999","scp_682","head","body","plant","grass","algae","cell","cancer","worm","flea","termite","ant","spider","fly","firefly","bee","stink_bug","human","bird","rat","frog","tadpole","fish","slug","snail","sapling","evergreen","cactus","kelp","coral","pistil","tree_branch","vine","bamboo_plant","mushroom_stalk","mushroom_gill","mushroom_cap","lichen","homunculus","root","hyphae","skin","porcelain"], + ignore: ["scp_063","head_049","body_049","shy_head","shy_body","head_049_1","body_049_1","head_008_1","body_008_1","head_012_1","body_012_1","scp_999","scp_682","head","body","plant","grass","algae","cell","cancer","worm","flea","termite","ant","spider","fly","firefly","bee","stink_bug","human","bird","rat","frog","tadpole","fish","slug","snail","sapling","evergreen","cactus","kelp","coral","pistil","tree_branch","vine","bamboo_plant","mushroom_stalk","mushroom_gill","mushroom_cap","lichen","homunculus","root","hyphae","skin","porcelain"], category: "scp", tempHigh: 190, stateHigh: ["molten_plastic","molten_plastic","fire","dioxin"], @@ -2904,7 +3301,7 @@ elements.shy_body = { category: "scp", pickElement: "scp_096", hardness: 1, - properties: { + properties: { dead: false, dir: 1, h: 0, @@ -3117,6 +3514,24 @@ elements.shy_body = { else if (isEmpty(pixel.x+pixel.dir, pixel.y+2) && !outOfBounds(pixel.x+pixel.dir, pixel.y+2) && isEmpty(pixel.x+pixel.dir, pixel.y+3) && !outOfBounds(pixel.x+pixel.dir, pixel.y+3)) { tryMove(head, pixel.x+pixel.dir, pixel.y+2) tryMove(pixel, pixel.x+pixel.dir, pixel.y+3) + } + else if (!isEmpty(pixel.x+pixel.dir, pixel.y) && !outOfBounds(pixel.x+pixel.dir, pixel.y) && isEmpty(pixel.x+pixel.dir, pixel.y-1) && !outOfBounds(pixel.x+pixel.dir, pixel.y-1)) { + if (pixelMap[pixel.x+pixel.dir][pixel.y].target == true) { + changePixel(pixelMap[pixel.x+pixel.dir][pixel.y], "blood") + } + else { + tryMove(head, pixel.x+pixel.dir, pixel.y+2) + if (isBreakable(pixelMap[pixel.x+pixel.dir][pixel.y])) { + breakPixel(pixelMap[pixel.x+pixel.dir][pixel.y]); + swapPixels(pixel, pixelMap[pixel.x+pixel.dir][pixel.y]) + } + else if (elements[pixelMap[pixel.x+pixel.dir][pixel.y].element].movable == true) { + swapPixels(pixel, pixelMap[pixel.x+pixel.dir][pixel.y]) + } + else if (elements[pixelMap[pixel.x+pixel.dir][pixel.y].element].hardness != 1 ) { + swapPixels(pixel, pixelMap[pixel.x+pixel.dir][pixel.y]) + } + } } else if (!isEmpty(pixel.x+pixel.dir, pixel.y) && !outOfBounds(pixel.x+pixel.dir, pixel.y) && !isEmpty(pixel.x+pixel.dir, pixel.y-1) && !outOfBounds(pixel.x+pixel.dir, pixel.y-1)) { if (pixelMap[pixel.x+pixel.dir][pixel.y].target == true) { @@ -3305,7 +3720,8 @@ elements.body_173 = { density: 2400, state: "solid", conduct: .025, - tempHigh: 1505, + tempHigh: 15050, + hardness: 1, stateHigh: ["magma","magma","magma","magma","rust","rust","rust","magma","magma","magma","magma","rust","rust","rust","spray_paint"], breakInto: ["concrete","concrete","concrete","concrete","rust","rust","rust","concrete","concrete","concrete","concrete","rust","rust","rust","spray_paint"], forceSaveColor: true, @@ -3580,7 +3996,8 @@ elements.head_173 = { density: 2400, state: "solid", conduct: .025, - tempHigh: 1505, + tempHigh: 15050, + hardness: 1, stateHigh: ["magma","magma","magma","magma","rust","rust","rust","magma","magma","magma","magma","rust","rust","rust","spray_paint"], breakInto: ["concrete","concrete","concrete","concrete","rust","rust","rust","concrete","concrete","concrete","concrete","rust","rust","rust","spray_paint"], forceSaveColor: true, @@ -3710,9 +4127,9 @@ elements.scp_229 = { "XX|SH%5|XX", ], category: "scp", - hardness: 0.85, + hardness: 0.25, breakInto: "metal_scrap", - tempHigh: 1750, + tempHigh: 1250, stateHigh: ["metal_scrap","metal_scrap","metal_scrap","metal_scrap","molten_glass","molten_plastic","molten_plastic"], properties: { radius: 10, @@ -3742,7 +4159,7 @@ elements.scp_229 = { for (var i = 0; i < coords.length; i++) { if (!isEmpty(coords[i].x,coords[i].y) && !outOfBounds(coords[i].x,coords[i].y)) { var electric = pixelMap[coords[i].x][coords[i].y] - if (elements[electric.element].category == "nervous system" && Math.random() > 0.5 || electric.element == "thunder_cloud" || electric.charge || electric.element == "scp_804" && electric.active == true || electric.element == "brain" || electric.element == "fish" || electric.element == "frog" || electric.element == "rat" || electric.element == "bird" || electric.element == "head" || electric.element == "head_1000" || electric.element == "head_035" || electric.element == "head_008" || electric.element == "battery" || electric.element == "electric" || electric.element == "lightning" || electric.element == "malware" || electric.element == "gray_goo") { + if (elements[electric.element].category == "nervous system" && Math.random() > 0.5 || electric.element == "thunder_cloud" || electric.charge || electric.element == "access_door" && Math.random() > 0.75 || electric.element == "keycard_terminal" || electric.element == "level_5" || electric.element == "scp_804" && electric.active == true || elements[electric.element].category == "logic" || electric.element == "brain" || electric.element == "fish" || electric.element == "frog" || electric.element == "rat" || electric.element == "bird" || electric.element == "head" || electric.element == "head_1000" || electric.element == "head_035" || electric.element == "head_008" || electric.element == "battery" || electric.element == "electric" || electric.element == "lightning" || electric.element == "malware" || electric.element == "gray_goo") { if (electric.y > pixel.y && electric.x > pixel.x && isEmpty(pixel.x+1,pixel.y+1)) { createPixel("scp_229",pixel.x+1,pixel.y+1) var electric2 = pixelMap[pixel.x+1][pixel.y+1] @@ -3830,7 +4247,7 @@ elements.scp_229 = { if (!isEmpty(x,y) && !outOfBounds(x,y) && pixel.nCD == undefined) { var electric = pixelMap[x][y] let old = electric.element; - if (electric.element == "brain" || electric.element == "thunder_cloud" || electric.element == "scp_804" && electric.active == true || elements[electric.element].category == "nervous system" && Math.random() > 0.5 || electric.element == "fish" || electric.element == "frog" || electric.element == "rat" || electric.element == "bird" || electric.element == "head" || electric.element == "head_035" || electric.element == "head_1000" || electric.element == "head_008" || elements[electric.element].category == "machines" && Math.random() > 0.5 || electric.element == "battery" || electric.element == "electric" || electric.element == "lightning" || electric.element == "malware" || electric.element == "gray_goo") { + if (electric.element == "brain" || electric.element == "access_door" || electric.element == "keycard_terminal" || electric.element == "level_4" || electric.element == "level_5" || electric.element == "thunder_cloud" || electric.element == "scp_804" && electric.active == true || elements[electric.element].category == "logic" || elements[electric.element].category == "nervous system" && Math.random() > 0.5 || electric.element == "fish" || electric.element == "frog" || electric.element == "rat" || electric.element == "bird" || electric.element == "head" || electric.element == "head_035" || electric.element == "head_1000" || electric.element == "head_008" || elements[electric.element].category == "machines" && Math.random() > 0.5 || electric.element == "battery" || electric.element == "electric" || electric.element == "lightning" || electric.element == "malware" || electric.element == "gray_goo") { deletePixel(electric.x,electric.y) createPixel("scp_229",electric.x,electric.y) electric = pixelMap[electric.x][electric.y] @@ -3843,7 +4260,7 @@ elements.scp_229 = { pixel.nCD = 2 } else if (electric.element == "site_nuke") { - explodeAt(electric.x,electric.y,100,["plasma","plasma","plasma","plasma","plasma","plasma","plasma","radiation","radiation","radiation","radiation","rad_steam","electric","electric"]) + explodeAt(electric.x,electric.y,300,["plasma","plasma","plasma","plasma","plasma","plasma","plasma","radiation","radiation","radiation","radiation","rad_steam","electric","electric"]) pixel.nCD = 2 } else if (electric.charge) { @@ -3877,6 +4294,7 @@ elements.scp_236 = { dir: 1, }, tick: function(pixel) { + doDefaults(pixel) if (Math.random() < 0.2) { pixel.dir = Math.random() < 0.5 ? 1 : -1 } @@ -4952,7 +5370,7 @@ elements.scp_804 = { } } } - else if (manmade.element == "unknown" || manmade.element == "site_nuke" || manmade.element == "scp_035" || manmade.element == "scp_229" || elements[manmade.element].category == "machines" || manmade.element == "metal_scrap" || manmade.element == "solid_mercury" || manmade.element == "molten_gallium" || manmade.element == "steel" || manmade.element == "galvanized_steel" || manmade.element == "brass" || manmade.element == "bronze" || manmade.element == "invar" || manmade.element == "sterling" || manmade.element == "rose_gold" || manmade.element == "purple_gold" || manmade.element == "blue_gold" || manmade.element == "electrum" || manmade.element == "solder" || manmade.element == "particleboard") { + else if (manmade.element == "unknown" || manmade.element == "site_nuke" || manmade.element == "scp_035" || manmade.element == "access_door" || manmade.element == "keycard_terminal" || manmade.element == "scp_229" || elements[manmade.element].category == "machines" || elements[manmade.element].category == "logic" || manmade.element == "metal_scrap" || manmade.element == "solid_mercury" || manmade.element == "molten_gallium" || manmade.element == "steel" || manmade.element == "galvanized_steel" || manmade.element == "brass" || manmade.element == "bronze" || manmade.element == "invar" || manmade.element == "sterling" || manmade.element == "rose_gold" || manmade.element == "purple_gold" || manmade.element == "blue_gold" || manmade.element == "electrum" || manmade.element == "solder" || manmade.element == "particleboard") { if (!manmade.repair) { manmade.repair = 15 } @@ -4987,7 +5405,7 @@ elements.scp_804 = { } } } - else if (!manmade.lc && !manmade.wc && manmade.element == "wood" || manmade.element == "tinder" || manmade.element == "scp_063" || manmade.element == "scp_012" || manmade.element == "dust" || manmade.element == "insulation" || manmade.element == "cloth" || manmade.element == "plastic" || manmade.element == "bead" || manmade.element == "glitter" || manmade.element == "confetti" || manmade.element == "paper" || manmade.element == "cement" || manmade.element == "acid" || manmade.element == "black_acid" || manmade.element == "alcohol" || manmade.element == "wax" || manmade.element == "poison" || manmade.element == "incense" || manmade.element == "gold_coin" || manmade.element == "borax" || manmade.element == "spray_paint" || manmade.element == "anesthesia" || manmade.element == "acid_gas" || manmade.element == "ball" || manmade.element == "potassium_salt" || manmade.element == "epsom_salt" || manmade.element == "sodium_acetate") { + else if (!manmade.lc && !manmade.wc && manmade.element == "wood" || manmade.element == "tinder" || manmade.element == "scp_063" || manmade.element == "scp_012" || manmade.element == "dust" || manmade.element == "insulation" || manmade.element == "cloth" || manmade.element == "plastic" || elements[manmade.element].keycard == true || manmade.element == "bead" || manmade.element == "glitter" || manmade.element == "confetti" || manmade.element == "paper" || manmade.element == "cement" || manmade.element == "acid" || manmade.element == "black_acid" || manmade.element == "alcohol" || manmade.element == "wax" || manmade.element == "poison" || manmade.element == "incense" || manmade.element == "gold_coin" || manmade.element == "borax" || manmade.element == "spray_paint" || manmade.element == "anesthesia" || manmade.element == "acid_gas" || manmade.element == "ball" || manmade.element == "potassium_salt" || manmade.element == "epsom_salt" || manmade.element == "sodium_acetate") { if (!manmade.repair) { manmade.repair = 6 } @@ -5003,7 +5421,7 @@ elements.scp_804 = { } } } - else if (manmade.panic && manmade.element == "bone" || manmade.panic && manmade.element == "quicklime" || manmade.panic && manmade.element == "rotten_meat" || manmade.panic && manmade.element == "meat" || manmade.element == "cooked_meat" || manmade.element == "blood" || manmade.element == "infection" || manmade.element == "seltzer" || Math.random() > 0.9 && manmade.element == "dirty_water" || manmade.element == "pool_water" || manmade.element == "lamp_oil" || manmade.element == "neutral_acid" || manmade.element == "glue" || manmade.element == "soda" || manmade.element == "melted_wax" || manmade.element == "chocolate_milk" || manmade.element == "fruit_milk" || manmade.element == "pilk" || manmade.element == "eggnog" || manmade.element == "cream" || manmade.element == "nut_milk" || manmade.element == "vinegar" || manmade.element == "soap" || manmade.element == "bleach" || manmade.element == "dye" || manmade.element == "ink" || manmade.element == "vaccine" || manmade.element == "antidote" || manmade.element == "tea" || manmade.element == "coffee" || manmade.element == "caramel" || manmade.element == "molasses" || manmade.element == "ketchup" || manmade.element == "sauce" || manmade.element == "mayo" || manmade.element == "cyanide") { + else if (manmade.panic && manmade.element == "bone" || elements[manmade.element].category == "medicine" || manmade.panic && manmade.element == "quicklime" || manmade.panic && manmade.element == "rotten_meat" || manmade.panic && manmade.element == "meat" || manmade.element == "cooked_meat" || manmade.element == "blood" || manmade.element == "infection" || manmade.element == "seltzer" || Math.random() > 0.9 && manmade.element == "dirty_water" || manmade.element == "pool_water" || manmade.element == "lamp_oil" || manmade.element == "neutral_acid" || manmade.element == "glue" || manmade.element == "soda" || manmade.element == "melted_wax" || manmade.element == "chocolate_milk" || manmade.element == "fruit_milk" || manmade.element == "pilk" || manmade.element == "eggnog" || manmade.element == "cream" || manmade.element == "nut_milk" || manmade.element == "vinegar" || manmade.element == "soap" || manmade.element == "bleach" || manmade.element == "dye" || manmade.element == "ink" || manmade.element == "vaccine" || manmade.element == "antidote" || manmade.element == "tea" || manmade.element == "coffee" || manmade.element == "caramel" || manmade.element == "molasses" || manmade.element == "ketchup" || manmade.element == "sauce" || manmade.element == "mayo" || manmade.element == "cyanide") { if (!manmade.repair) { manmade.repair = 3 } @@ -5632,24 +6050,10 @@ elements.body_1015 = { return } - if (Math.random() < 0.5) { - let yDir = -1 - for (let y = 1; y < height; y++) { - let x2 = pixel.x - let y2 = pixel.y+(y*yDir); - let weight = 0 - if (!isEmpty(x2,y2,true) && !outOfBounds(x2,y2)) { - weight++ - } - if (isEmpty(x2,y2,true) || outOfBounds(x2,y2)) { - if (weight > 4) { - changePixel(pixel,"scp_1015") - releaseElement(pixel,"blood") - } - } - } - } - + if (Math.random() < 0.25 && !isEmpty(pixel.x-1,pixel.y+1) && !isEmpty(pixel.x+1,pixel.y+1) && !isEmpty(pixel.x-1,pixel.y-1) && !isEmpty(pixel.x+1,pixel.y-1) && !isEmpty(pixel.x,pixel.y-1) && !isEmpty(pixel.x,pixel.y+1) && !isEmpty(pixel.x-1,pixel.y) && !isEmpty(pixel.x+1,pixel.y) && Math.random() > 0.5) { + changePixel(pixel,"scp_1015") + releaseElement(pixel,"blood",4,true) + } // Find the head if (!isEmpty(pixel.x, pixel.y-1, true) && pixelMap[pixel.x][pixel.y-1].element == "head_1015") { var head = pixelMap[pixel.x][pixel.y-1]; @@ -6181,6 +6585,52 @@ elements.scp_1147_leaf = { forceSaveColor: true } */ +elements.scp_1424 = { + name: "SCP-1424", + color: ["#E7E7E5","#DCD9D4","#ACACAC"], + temp: -23, + properties: { + dir: 1, + }, + tick: function(pixel) { + if (tryMove(pixel, pixel.x, pixel.y+1)) {} // Fall + doDefaults(pixel); + if (Math.random() < 0.05) { // Move 5% 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])) { + 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) { + moved = true; + break; + } + } + } + // 10% chance to change direction + if (Math.random() < 0.1 || !moved) { + pixel.dir *= -1; + } + } + if (Math.random() > 0.9 && Math.random() > 0.9) { + releaseElement(pixel,"ammonia",1,true) + } + if (pixel.temp > -17) { pixel.temp -= 1; } + else if (pixel.temp < -22) { pixel.temp += 1; } + }, + category: "scp", + density: 1580, + state: "solid", + conduct: .025, + cooldown: defaultCooldown, +} + elements.scp_1600 = { name: "SCP-1600-1", color: "#D6CE02", @@ -6254,7 +6704,7 @@ elements.scp_1600 = { pixel.color = "rgb("+avg.join(",")+")"; } }, - ignore: ["scp_1600_1","gallium","brass","zinc","sulfur","body_173","head_173","body_096","head_096","body_049","head_049","scp_035","scp_1015","scp_999","scp_063","scp_055"], + ignore: ["scp_1600_1","gallium","brass","zinc","sulfur","body_173","head_173","shy_body","shy_head","body_049","head_049","scp_035","scp_1015","scp_999","scp_063","scp_055"], canPlace: true, reactions: { "scp_682":{ stain2:"#CA8E2F", chance:0.05,}, From c1b233c1357f621e1777e0abc55253a497bf223d Mon Sep 17 00:00:00 2001 From: David Kopal <112717418+DavidKopal@users.noreply.github.com> Date: Fri, 3 Oct 2025 19:00:38 +0200 Subject: [PATCH 2/5] Add files via upload --- mods/more_cells.js | 414 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 414 insertions(+) create mode 100644 mods/more_cells.js diff --git a/mods/more_cells.js b/mods/more_cells.js new file mode 100644 index 00000000..9ff56ebc --- /dev/null +++ b/mods/more_cells.js @@ -0,0 +1,414 @@ +viewInfo[4] = { // energy view + name: "enrg", + pixel: function (pixel, ctx) { + if (elements[pixel.element].isCell === true) { + var stat = pixel.energy + var ratio = Math.log(stat) / Math.log(3000) + var hue = Math.round(ratio * 240) + if (hue < 0) hue = 0 + if (hue > 240) hue = 240 + drawSquare(ctx, `hsl(${hue},100%,50%)`, pixel.x, pixel.y) + } + } +} + +viewInfo[5] = { // breath view + name: "brth", + pixel: function (pixel, ctx) { + if (elements[pixel.element].isCell === true) { + var stat = pixel.breath + var ratio = Math.log(stat) / Math.log(3000) + var hue = Math.round(ratio * 240) + if (hue < 0) hue = 0 + if (hue > 240) hue = 240 + drawSquare(ctx, `hsl(${hue},100%,50%)`, pixel.x, pixel.y) + } + } +} + + +function baseCellTick(px) { + if (!elements[px.element].isCell) { return } + + if (px.energy > 3000) { px.energy = 3000 } + if (px.breath > 3000) { px.breath = 3000 } + + if (!px.static && Math.random() < 0.115) { + px.energy-- + px.breath-- + } + + if (px.energy < 1 || px.breath < 1) { + changePixel(px, "cancer") + return + } + + const ns = getNeighbors(px) + ns.forEach(n => { + if (!elements[n.element].isCell) { return } + + if (n.energy < px.energy) { + let transfer = (px.energy - n.energy) / 4 + transfer = Math.floor(Math.min(transfer, (px.transfer + n.transfer) / 2)) + px.energy -= transfer + n.energy += transfer + } + + if (n.breath < px.breath) { + let transfer = Math.floor((px.breath - n.breath) / 4) + transfer = Math.min(transfer, (px.transfer + n.transfer) / 2) + px.breath -= transfer + n.breath += transfer + } + + }) +} + +elements.chlorocyte = { + color: ["#00ff00", "#00a500", "#008a00", "#26a026", "#3eff3e"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 1 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + px.energy += (4 - getNeighbors(px).length) * 3 + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "steam", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "ice", "sugar_ice"], + state: "solid", + density: 1000.1, + category: "cells", + breakInto: ["water", "dna", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 } + } +} + +elements.nucleolyte = { + color: "#FF6F3C", + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 1 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + const ns = getNeighbors(px) + for (let n of ns) { + if (n.element == "vena" && n.charge) { + px.breath += 80 + px.energy += 80 + break + } + } + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "steam", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "ice", "sugar_ice"], + state: "solid", + density: 1000.1, + category: "cells", + breakInto: ["sugar_water", "dna", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 } + } +} + +elements.respira = { + color: ["#8888ff"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 1 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + px.breath += (4 - getNeighbors(px).length) * 3 + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "steam", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "ice", "sugar_ice"], + state: "solid", + density: 1000.1, + category: "cells", + breakInto: ["water", "dna", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 } + } +} + +elements.structura = { + color: ["#535353"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 0, + static: true, + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "steam", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "ice", "sugar_ice"], + state: "solid", + density: 1000.1, + category: "cells", + breakInto: ["water", "dna", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 } + } +} + +elements.vena = { + color: ["#a85e5e"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 0, + static: false, + }, + conduct: 1, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + if (px.charge) { + px.transfer = 500 + px.static = true + } else { + transfer = 0 + px.static = false + } + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "sugar_water", "sugar_water"], + tempLow: -2, + stateLow: ["ice", "ice", "sugar_ice", "sugar_ice"], + state: "solid", + density: 1010, + category: "cells", + breakInto: ["sugar_water", "sugar_water", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 } + } +} + +elements.neurocell = { + color: ["#5e5fa8"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 50, + cd: 1 + }, + conduct: 1, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + px.cd-- + if (px.cd < 1) { + px.cd = 20 + px.charge = 1 + } + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "sugar_water", "sugar_water"], + tempLow: -2, + stateLow: ["ice", "ice", "sugar_ice", "sugar_ice"], + state: "solid", + density: 1010, + category: "cells", + breakInto: ["sugar_water", "sugar_water", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 } + } +} + +elements.insulon = { + color: ["#cadf7e"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 1 + }, + conduct: 1, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + if (px.temp > 20) { + px.temp -= 6 + } + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 300, + stateHigh: ["steam", "steam", "steam", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "ice", "sugar_ice"], + state: "solid", + density: 1000.1, + category: "cells", + breakInto: ["water", "dna", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 } + } +} + +elements.carapace = { + color: ["#46065a"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 0 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 1200, + stateHigh: ["steam", "molten_copper", "steam", "sugar"], + state: "solid", + density: 1800, + category: "cells", + breakInto: ["water", "oxidized_copper", "dna", "dna"], +} + +elements.phagocyte = { + color: ["#a3d9a6"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 0 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "sugar", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "sugar_ice", "sugar_ice"], + state: "solid", + density: 1010, + category: "cells", + breakInto: ["dna", "sugar", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem2: "stem_cell", chance: 0.055 }, + infection: { elem2: "stem_cell", chance: 0.075 }, + poison: { elem2: "stem_cell", chance: 0.025 }, + } +} + +elements.stem_cell = { + color: ["#c0c0c0"], + behavior: behaviors.LIQUID, + noMix: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + const ns = getNeighbors(px) + if (ns.length > 0) { + const elem = ns[Math.floor(Math.random() * ns.length)].element + if (elements[elem].isCell) { + changePixel(px, elem) + } + } + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "sugar", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "sugar_ice", "sugar_ice"], + state: "solid", + density: 1010, + category: "cells", + breakInto: ["dna", "sugar", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 } + } +} + +elements.cancer.reactions.chlorocyte = { elem2: "cancer", chane: 0.005 } +elements.cancer.reactions.respira = { elem2: "cancer", chane: 0.005 } +elements.cancer.reactions.insulon = { elem2: "cancer", chane: 0.005 } +elements.cancer.reactions.neurocell = { elem2: "cancer", chane: 0.005 } +elements.cancer.reactions.vena = { elem2: "cancer", chane: 0.005 } + +elements.infection.reactions.chlorocyte = { elem2: "infection", chane: 0.0015 } +elements.infection.reactions.respira = { elem2: "infection", chane: 0.0015 } +elements.infection.reactions.insulon = { elem2: "infection", chane: 0.0015 } +elements.infection.reactions.neurocell = { elem2: "infection", chane: 0.0015 } +elements.infection.reactions.vena = { elem2: "infection", chane: 0.0015 } \ No newline at end of file From 851b3d9cb4957fc881b056a45ad4f489ad5aa157 Mon Sep 17 00:00:00 2001 From: Nekonico <163950752+DBNekonico@users.noreply.github.com> Date: Fri, 3 Oct 2025 21:44:58 -0700 Subject: [PATCH 3/5] more fixes --- mods/scp.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mods/scp.js b/mods/scp.js index 68257180..8c6b2aba 100644 --- a/mods/scp.js +++ b/mods/scp.js @@ -2174,7 +2174,7 @@ elements.scp_035 = { color: ["#f7ead0","#faf9f6","#e9e6db"], buttonColor: ["#11111f","#f7ead0","#f7ead0","#f7ead0","#f7ead0","#11111f","#faf9f6","#faf9f6","#faf9f6","#faf9f6","#11111f","#e9e6db","#e9e6db","#e9e6db","#e9e6db","#11111f"], name: "SCP-035", - hardness: 0.6, + hardness: 0.9, category: "scp", behavior: [ "CR:black_acid%0.05|CR:black_acid%0.25|CR:black_acid%0.05", @@ -3946,6 +3946,8 @@ elements.body_173 = { break; } } + pixel.frozen1 = false + break; } if (x >= 99) { pixel.frozen1 = false @@ -3978,6 +3980,8 @@ elements.body_173 = { break; } } + pixel.frozen2 = false + break; } if (x <= -99) { pixel.frozen2 = false @@ -5421,7 +5425,7 @@ elements.scp_804 = { } } } - else if (manmade.panic && manmade.element == "bone" || elements[manmade.element].category == "medicine" || manmade.panic && manmade.element == "quicklime" || manmade.panic && manmade.element == "rotten_meat" || manmade.panic && manmade.element == "meat" || manmade.element == "cooked_meat" || manmade.element == "blood" || manmade.element == "infection" || manmade.element == "seltzer" || Math.random() > 0.9 && manmade.element == "dirty_water" || manmade.element == "pool_water" || manmade.element == "lamp_oil" || manmade.element == "neutral_acid" || manmade.element == "glue" || manmade.element == "soda" || manmade.element == "melted_wax" || manmade.element == "chocolate_milk" || manmade.element == "fruit_milk" || manmade.element == "pilk" || manmade.element == "eggnog" || manmade.element == "cream" || manmade.element == "nut_milk" || manmade.element == "vinegar" || manmade.element == "soap" || manmade.element == "bleach" || manmade.element == "dye" || manmade.element == "ink" || manmade.element == "vaccine" || manmade.element == "antidote" || manmade.element == "tea" || manmade.element == "coffee" || manmade.element == "caramel" || manmade.element == "molasses" || manmade.element == "ketchup" || manmade.element == "sauce" || manmade.element == "mayo" || manmade.element == "cyanide") { + else if (manmade.panic && manmade.element == "bone" || elements[manmade.element].category == "medicine" || manmade.panic && manmade.element == "quicklime" || manmade.panic && manmade.element == "rotten_meat" || manmade.panic && manmade.element == "meat" || manmade.element == "cooked_meat" || manmade.element == "blood" || manmade.element == "infection" || manmade.element == "infected_blood" || manmade.element == "seltzer" || Math.random() > 0.9 && manmade.element == "dirty_water" || manmade.element == "pool_water" || manmade.element == "lamp_oil" || manmade.element == "neutral_acid" || manmade.element == "glue" || manmade.element == "soda" || manmade.element == "melted_wax" || manmade.element == "chocolate_milk" || manmade.element == "fruit_milk" || manmade.element == "pilk" || manmade.element == "eggnog" || manmade.element == "cream" || manmade.element == "nut_milk" || manmade.element == "vinegar" || manmade.element == "soap" || manmade.element == "bleach" || manmade.element == "dye" || manmade.element == "ink" || manmade.element == "vaccine" || manmade.element == "antidote" || manmade.element == "tea" || manmade.element == "coffee" || manmade.element == "caramel" || manmade.element == "molasses" || manmade.element == "ketchup" || manmade.element == "sauce" || manmade.element == "mayo" || manmade.element == "cyanide") { if (!manmade.repair) { manmade.repair = 3 } From e2e995ab9d0a1024e74679fe452da25f45afe33c Mon Sep 17 00:00:00 2001 From: David Kopal <112717418+DavidKopal@users.noreply.github.com> Date: Sat, 4 Oct 2025 13:57:31 +0200 Subject: [PATCH 4/5] Delete mods/more_cells.js --- mods/more_cells.js | 414 --------------------------------------------- 1 file changed, 414 deletions(-) delete mode 100644 mods/more_cells.js diff --git a/mods/more_cells.js b/mods/more_cells.js deleted file mode 100644 index 9ff56ebc..00000000 --- a/mods/more_cells.js +++ /dev/null @@ -1,414 +0,0 @@ -viewInfo[4] = { // energy view - name: "enrg", - pixel: function (pixel, ctx) { - if (elements[pixel.element].isCell === true) { - var stat = pixel.energy - var ratio = Math.log(stat) / Math.log(3000) - var hue = Math.round(ratio * 240) - if (hue < 0) hue = 0 - if (hue > 240) hue = 240 - drawSquare(ctx, `hsl(${hue},100%,50%)`, pixel.x, pixel.y) - } - } -} - -viewInfo[5] = { // breath view - name: "brth", - pixel: function (pixel, ctx) { - if (elements[pixel.element].isCell === true) { - var stat = pixel.breath - var ratio = Math.log(stat) / Math.log(3000) - var hue = Math.round(ratio * 240) - if (hue < 0) hue = 0 - if (hue > 240) hue = 240 - drawSquare(ctx, `hsl(${hue},100%,50%)`, pixel.x, pixel.y) - } - } -} - - -function baseCellTick(px) { - if (!elements[px.element].isCell) { return } - - if (px.energy > 3000) { px.energy = 3000 } - if (px.breath > 3000) { px.breath = 3000 } - - if (!px.static && Math.random() < 0.115) { - px.energy-- - px.breath-- - } - - if (px.energy < 1 || px.breath < 1) { - changePixel(px, "cancer") - return - } - - const ns = getNeighbors(px) - ns.forEach(n => { - if (!elements[n.element].isCell) { return } - - if (n.energy < px.energy) { - let transfer = (px.energy - n.energy) / 4 - transfer = Math.floor(Math.min(transfer, (px.transfer + n.transfer) / 2)) - px.energy -= transfer - n.energy += transfer - } - - if (n.breath < px.breath) { - let transfer = Math.floor((px.breath - n.breath) / 4) - transfer = Math.min(transfer, (px.transfer + n.transfer) / 2) - px.breath -= transfer - n.breath += transfer - } - - }) -} - -elements.chlorocyte = { - color: ["#00ff00", "#00a500", "#008a00", "#26a026", "#3eff3e"], - behavior: behaviors.WALL, - noMix: true, - properties: { - energy: 300, - breath: 300, - transfer: 1 - }, - isCell: true, - hoverStat: function (px) { - return `E:${px.energy} B:${px.breath}` - }, - tick: (px) => { - px.energy += (4 - getNeighbors(px).length) * 3 - baseCellTick(px) - doDefaults(px) - }, - tempHigh: 102, - stateHigh: ["steam", "steam", "steam", "sugar"], - tempLow: -2, - stateLow: ["ice", "ice", "ice", "sugar_ice"], - state: "solid", - density: 1000.1, - category: "cells", - breakInto: ["water", "dna", "dna", "dna"], - reactions: { - ...elements.cell.reactions, - cancer: { elem1: "cancer", chance: 0.005 } - } -} - -elements.nucleolyte = { - color: "#FF6F3C", - behavior: behaviors.WALL, - noMix: true, - properties: { - energy: 300, - breath: 300, - transfer: 1 - }, - isCell: true, - hoverStat: function (px) { - return `E:${px.energy} B:${px.breath}` - }, - tick: (px) => { - const ns = getNeighbors(px) - for (let n of ns) { - if (n.element == "vena" && n.charge) { - px.breath += 80 - px.energy += 80 - break - } - } - baseCellTick(px) - doDefaults(px) - }, - tempHigh: 102, - stateHigh: ["steam", "steam", "steam", "sugar"], - tempLow: -2, - stateLow: ["ice", "ice", "ice", "sugar_ice"], - state: "solid", - density: 1000.1, - category: "cells", - breakInto: ["sugar_water", "dna", "dna", "dna"], - reactions: { - ...elements.cell.reactions, - cancer: { elem1: "cancer", chance: 0.005 } - } -} - -elements.respira = { - color: ["#8888ff"], - behavior: behaviors.WALL, - noMix: true, - properties: { - energy: 300, - breath: 300, - transfer: 1 - }, - isCell: true, - hoverStat: function (px) { - return `E:${px.energy} B:${px.breath}` - }, - tick: (px) => { - px.breath += (4 - getNeighbors(px).length) * 3 - baseCellTick(px) - doDefaults(px) - }, - tempHigh: 102, - stateHigh: ["steam", "steam", "steam", "sugar"], - tempLow: -2, - stateLow: ["ice", "ice", "ice", "sugar_ice"], - state: "solid", - density: 1000.1, - category: "cells", - breakInto: ["water", "dna", "dna", "dna"], - reactions: { - ...elements.cell.reactions, - cancer: { elem1: "cancer", chance: 0.005 } - } -} - -elements.structura = { - color: ["#535353"], - behavior: behaviors.WALL, - noMix: true, - properties: { - energy: 300, - breath: 300, - transfer: 0, - static: true, - }, - isCell: true, - hoverStat: function (px) { - return `E:${px.energy} B:${px.breath}` - }, - tick: (px) => { - baseCellTick(px) - doDefaults(px) - }, - tempHigh: 102, - stateHigh: ["steam", "steam", "steam", "sugar"], - tempLow: -2, - stateLow: ["ice", "ice", "ice", "sugar_ice"], - state: "solid", - density: 1000.1, - category: "cells", - breakInto: ["water", "dna", "dna", "dna"], - reactions: { - ...elements.cell.reactions, - cancer: { elem1: "cancer", chance: 0.005 } - } -} - -elements.vena = { - color: ["#a85e5e"], - behavior: behaviors.WALL, - noMix: true, - properties: { - energy: 300, - breath: 300, - transfer: 0, - static: false, - }, - conduct: 1, - isCell: true, - hoverStat: function (px) { - return `E:${px.energy} B:${px.breath}` - }, - tick: (px) => { - if (px.charge) { - px.transfer = 500 - px.static = true - } else { - transfer = 0 - px.static = false - } - baseCellTick(px) - doDefaults(px) - }, - tempHigh: 102, - stateHigh: ["steam", "steam", "sugar_water", "sugar_water"], - tempLow: -2, - stateLow: ["ice", "ice", "sugar_ice", "sugar_ice"], - state: "solid", - density: 1010, - category: "cells", - breakInto: ["sugar_water", "sugar_water", "dna", "dna"], - reactions: { - ...elements.cell.reactions, - cancer: { elem1: "cancer", chance: 0.005 } - } -} - -elements.neurocell = { - color: ["#5e5fa8"], - behavior: behaviors.WALL, - noMix: true, - properties: { - energy: 300, - breath: 300, - transfer: 50, - cd: 1 - }, - conduct: 1, - isCell: true, - hoverStat: function (px) { - return `E:${px.energy} B:${px.breath}` - }, - tick: (px) => { - px.cd-- - if (px.cd < 1) { - px.cd = 20 - px.charge = 1 - } - baseCellTick(px) - doDefaults(px) - }, - tempHigh: 102, - stateHigh: ["steam", "steam", "sugar_water", "sugar_water"], - tempLow: -2, - stateLow: ["ice", "ice", "sugar_ice", "sugar_ice"], - state: "solid", - density: 1010, - category: "cells", - breakInto: ["sugar_water", "sugar_water", "dna", "dna"], - reactions: { - ...elements.cell.reactions, - cancer: { elem1: "cancer", chance: 0.005 } - } -} - -elements.insulon = { - color: ["#cadf7e"], - behavior: behaviors.WALL, - noMix: true, - properties: { - energy: 300, - breath: 300, - transfer: 1 - }, - conduct: 1, - isCell: true, - hoverStat: function (px) { - return `E:${px.energy} B:${px.breath}` - }, - tick: (px) => { - if (px.temp > 20) { - px.temp -= 6 - } - baseCellTick(px) - doDefaults(px) - }, - tempHigh: 300, - stateHigh: ["steam", "steam", "steam", "sugar"], - tempLow: -2, - stateLow: ["ice", "ice", "ice", "sugar_ice"], - state: "solid", - density: 1000.1, - category: "cells", - breakInto: ["water", "dna", "dna", "dna"], - reactions: { - ...elements.cell.reactions, - cancer: { elem1: "cancer", chance: 0.005 } - } -} - -elements.carapace = { - color: ["#46065a"], - behavior: behaviors.WALL, - noMix: true, - properties: { - energy: 300, - breath: 300, - transfer: 0 - }, - isCell: true, - hoverStat: function (px) { - return `E:${px.energy} B:${px.breath}` - }, - tick: (px) => { - baseCellTick(px) - doDefaults(px) - }, - tempHigh: 1200, - stateHigh: ["steam", "molten_copper", "steam", "sugar"], - state: "solid", - density: 1800, - category: "cells", - breakInto: ["water", "oxidized_copper", "dna", "dna"], -} - -elements.phagocyte = { - color: ["#a3d9a6"], - behavior: behaviors.WALL, - noMix: true, - properties: { - energy: 300, - breath: 300, - transfer: 0 - }, - isCell: true, - hoverStat: function (px) { - return `E:${px.energy} B:${px.breath}` - }, - tick: (px) => { - baseCellTick(px) - doDefaults(px) - }, - tempHigh: 102, - stateHigh: ["steam", "steam", "sugar", "sugar"], - tempLow: -2, - stateLow: ["ice", "ice", "sugar_ice", "sugar_ice"], - state: "solid", - density: 1010, - category: "cells", - breakInto: ["dna", "sugar", "dna", "dna"], - reactions: { - ...elements.cell.reactions, - cancer: { elem2: "stem_cell", chance: 0.055 }, - infection: { elem2: "stem_cell", chance: 0.075 }, - poison: { elem2: "stem_cell", chance: 0.025 }, - } -} - -elements.stem_cell = { - color: ["#c0c0c0"], - behavior: behaviors.LIQUID, - noMix: true, - hoverStat: function (px) { - return `E:${px.energy} B:${px.breath}` - }, - tick: (px) => { - const ns = getNeighbors(px) - if (ns.length > 0) { - const elem = ns[Math.floor(Math.random() * ns.length)].element - if (elements[elem].isCell) { - changePixel(px, elem) - } - } - doDefaults(px) - }, - tempHigh: 102, - stateHigh: ["steam", "steam", "sugar", "sugar"], - tempLow: -2, - stateLow: ["ice", "ice", "sugar_ice", "sugar_ice"], - state: "solid", - density: 1010, - category: "cells", - breakInto: ["dna", "sugar", "dna", "dna"], - reactions: { - ...elements.cell.reactions, - cancer: { elem1: "cancer", chance: 0.005 } - } -} - -elements.cancer.reactions.chlorocyte = { elem2: "cancer", chane: 0.005 } -elements.cancer.reactions.respira = { elem2: "cancer", chane: 0.005 } -elements.cancer.reactions.insulon = { elem2: "cancer", chane: 0.005 } -elements.cancer.reactions.neurocell = { elem2: "cancer", chane: 0.005 } -elements.cancer.reactions.vena = { elem2: "cancer", chane: 0.005 } - -elements.infection.reactions.chlorocyte = { elem2: "infection", chane: 0.0015 } -elements.infection.reactions.respira = { elem2: "infection", chane: 0.0015 } -elements.infection.reactions.insulon = { elem2: "infection", chane: 0.0015 } -elements.infection.reactions.neurocell = { elem2: "infection", chane: 0.0015 } -elements.infection.reactions.vena = { elem2: "infection", chane: 0.0015 } \ No newline at end of file From 87b14daf94c094b9ca1c516799df9e71bdfbb256 Mon Sep 17 00:00:00 2001 From: David Kopal <112717418+DavidKopal@users.noreply.github.com> Date: Sat, 4 Oct 2025 13:58:46 +0200 Subject: [PATCH 5/5] Add files via upload --- mods/organism.js | 915 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 915 insertions(+) create mode 100644 mods/organism.js diff --git a/mods/organism.js b/mods/organism.js new file mode 100644 index 00000000..d1aec81e --- /dev/null +++ b/mods/organism.js @@ -0,0 +1,915 @@ +// heavily inspired by biology.js, go try it out too! +viewInfo[4] = { + name: "enrg", + pixel: function (pixel, ctx) { + if (elements[pixel.element].isCell === true) { + var stat = pixel.energy + var ratio = stat / 3000 + if (ratio < 0) ratio = 0 + if (ratio > 1) ratio = 1 + var hue = Math.round(ratio * 180) + drawSquare(ctx, `hsl(${hue},100%,50%)`, pixel.x, pixel.y) + } + } +} + +viewInfo[5] = { + name: "brth", + pixel: function (pixel, ctx) { + if (elements[pixel.element].isCell === true) { + var stat = pixel.breath + var ratio = stat / 3000 + if (ratio < 0) ratio = 0 + if (ratio > 1) ratio = 1 + var hue = Math.round(ratio * 180) + drawSquare(ctx, `hsl(${hue},100%,50%)`, pixel.x, pixel.y) + } + } +} + +viewInfo[6] = { + name: "wste", + pixel: function (pixel, ctx) { + if (elements[pixel.element].properties?.waste !== undefined) { + let stat = pixel.waste || 1 + let ratio = Math.log(stat) / Math.log(500) + if (ratio < 0) ratio = 0 + if (ratio > 1) ratio = 1 + let hue = 120 - Math.round(ratio * 120) + drawSquare(ctx, `hsl(${hue},100%,50%)`, pixel.x, pixel.y) + } + } +} + +function baseCellTick(px) { + if (!elements[px.element].isCell) { return } + + if (px.energy > 3000) { px.energy = 3000 } + if (px.breath > 3000) { px.breath = 3000 } + + if (!px.static && Math.random() < 0.115) { + px.energy -= 2 + px.breath -= 2 + } + + if (px.energy < 1 || px.breath < 1 || (px.waste > 500 && px.element !== "urocyte") || px.waste > 3000) { + changePixel(px, "infection") + return + } + + const ns = getNeighbors(px) + ns.forEach(n => { + if (!elements[n.element].isCell) { return } + + if (n.energy < px.energy) { + let transfer = (px.energy - n.energy) / 4 + transfer = Math.floor(Math.min(transfer, (px.transfer + n.transfer) / 2)) + px.energy -= transfer + n.energy += transfer + } else if (n.energy > px.energy) { + let transfer = (n.energy - px.energy) / 4 + transfer = Math.floor(Math.min(transfer, (px.transfer + n.transfer) / 2)) + px.energy += transfer + n.energy -= transfer + } + + if (n.breath < px.breath) { + let transfer = (px.breath - n.breath) / 4 + transfer = Math.floor(Math.min(transfer, (px.transfer + n.transfer) / 2)) + px.breath -= transfer + n.breath += transfer + } else if (n.breath > px.breath) { + let transfer = (n.breath - px.breath) / 4 + transfer = Math.floor(Math.min(transfer, (px.transfer + n.transfer) / 2)) + px.breath += transfer + n.breath -= transfer + } + + }) +} + +elements.chlorocyte = { // generates energy per air pixel next to it + color: ["#00ff00", "#00a500", "#008a00", "#26a026", "#3eff3e"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 1 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + px.energy += (4 - getNeighbors(px).length) * 3 + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "steam", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "ice", "sugar_ice"], + state: "solid", + density: 1000.1, + category: "nutrients", + breakInto: ["water", "dna", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 }, + sugar: undefined, + sugar_water: undefined, + }, + movable: false +} + +elements.fermentocyte = { // stores and ferments sugar into energy + color: "#FF6F3C", + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 1, + waste: 0, + sugar: 0 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + if (px.sugar + 1 < 5) { + const ns = getNeighbors(px) + for (let n of ns) { + if (n.element == "sugar") { + deletePixel(n.x, n.y) + px.sugar++ + break + } + } + } + if (px.sugar) { + px.sugar -= 0.0034 + px.energy += 50 + px.waste += 0.5 + if (px.sugar < 0) { px.sugar = 0 } + } + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "steam", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "ice", "sugar_ice"], + state: "solid", + density: 1000.1, + category: "nutrients", + breakInto: ["sugar_water", "dna", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 }, + sugar: undefined, + sugar_water: undefined, + }, + movable: false +} + +elements.urocyte = { + color: "#927d07", + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + waste: 0, + inWaste: true, + transfer: 1 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + if (px.waste >= 400) { + if (isEmpty(px.x, px.y + 1)) { + createPixel("waste", px.x, px.y + 1) + px.waste -= 400 + } else if (isEmpty(px.x + 1, px.y)) { + createPixel("waste", px.x + 1, px.y) + px.waste -= 400 + } else if (isEmpty(px.x - 1, px.y)) { + createPixel("waste", px.x - 1, px.y) + px.waste -= 400 + } + } + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "steam", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "ice", "sugar_ice"], + state: "solid", + density: 1000.1, + category: "waste", + breakInto: ["water", "dna", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 }, + sugar: undefined, + sugar_water: undefined, + }, + movable: false +} + +elements.root = { // stores water and converts it into energy + color: ["#fff0c0", "#bba86c"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 2, + water: 0 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + const ns = getNeighbors(px) + ns.forEach(n => { + if (n.element == "water") { + deletePixel(n.x, n.y) + px.water += 2 + } else if (n.element == "root") { + if (n.energy < px.energy) { + let transfer = (px.energy - n.energy) / 4 + transfer = Math.floor(Math.min(transfer, 40 / 2)) + px.energy -= transfer + n.energy += transfer + } else if (n.energy > px.energy) { + let transfer = (n.breath - px.breath) / 4 + transfer = Math.floor(Math.min(transfer, (px.transfer + n.transfer) / 2)) + px.energy += transfer + n.energy -= transfer + } + + if (n.breath < px.breath) { + let transfer = (px.breath - n.breath) / 4 + transfer = Math.floor(Math.min(transfer, (px.transfer + n.transfer) / 2)) + px.breath -= transfer + n.breath += transfer + } else if (n.breath > px.breath) { + let transfer = (n.breath - px.breath) / 4 + transfer = Math.floor(Math.min(transfer, (px.transfer + n.transfer) / 2)) + px.breath += transfer + n.breath -= transfer + } + } else if (n.element == "sugar_water") { + deletePixel(n.x, n.y) + px.water += 3 + } else if (n.element == "mud") { + changePixel(n, "dirt") + px.water += 5 + } else if (n.element == "wet_sand") { + changePixel(n, "sand") + px.water += 5 + } else if (n.element == "dirt" && Math.random() < 0.075) { + px.water += 1 + } else if (n.element == "sand" && Math.random() < 0.025) { + px.water += 1 + } + }) + if (px.water > 0 && Math.random() < 0.185) { + px.water -= 1 + px.energy += 15 + if (px.water < 0) { px.water = 0 } + } + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "steam", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "ice", "sugar_ice"], + state: "solid", + density: 1000.1, + category: "nutrients", + breakInto: ["sugar_water", "dna", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 }, + sugar: undefined, + sugar_water: undefined, + }, + movable: false, + isFood: true +} + +elements.lipocyte = { // stores excess energy for later use + color: "#FFE680", + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 30, + fat: 0 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + if (px.energy >= 1300 && px.fat < 18) { + px.energy -= 1000 + px.fat += 1 + } else if (px.energy <= 300 && px.fat > 0 && Math.random() < 0.1875) { + px.fat -= 1 + px.energy += 1000 + } + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "steam", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "ice", "sugar_ice"], + state: "solid", + density: 1000.1, + category: "nutrients", + breakInto: ["sugar_water", "dna", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 }, + sugar: undefined, + sugar_water: undefined, + }, + movable: false +} + +elements.aerocyte = { // generates breath out of energy + color: "#66ccff", + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + waste: 0, + transfer: 30, + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + if (px.energy >= 305 && px.breath <= 1995) { + px.energy -= 5 + px.breath += 5 + px.waste += 0.075 + } + + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "steam", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "ice", "sugar_ice"], + state: "solid", + density: 1000.1, + category: "breathing", + breakInto: ["sugar_water", "dna", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 }, + sugar: undefined, + sugar_water: undefined, + }, + movable: false +} + +elements.respira = { // just like chlorocyte, but for breath + color: ["#8888ff"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 1 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + px.breath += (4 - getNeighbors(px).length) * 3 + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "steam", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "ice", "sugar_ice"], + state: "solid", + density: 1000.1, + category: "breathing", + breakInto: ["water", "dna", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 }, + sugar: undefined, + sugar_water: undefined, + }, + movable: false +} + +elements.vena = { // transfers energy when powered + color: ["#a85e5e"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 0, + static: false, + waste: 0 + }, + conduct: 1, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + if (px.charge) { + px.transfer = 500 + px.static = true + } else { + px.transfer = 0 + px.static = false + } + + if (px.energy > 3000) { px.energy = 3000 } + if (px.breath > 3000) { px.breath = 3000 } + + if (!px.static && Math.random() < 0.115) { + px.energy -= 2 + px.breath -= 2 + } + + if (px.energy < 1 || px.breath < 1 || (px.waste > 500 && px.element !== "urocyte") || px.waste > 3000) { + changePixel(px, "infection") + return + } + + const ns = getNeighbors(px) + ns.forEach(n => { + if (!elements[n.element].isCell) { return } + + if (n.energy < px.energy) { + let transfer = (px.energy - n.energy) / 4 + transfer = Math.floor(Math.min(transfer, (px.transfer + n.transfer) / 2)) + px.energy -= transfer + n.energy += transfer + } else if (n.energy > px.energy) { + let transfer = (n.energy - px.energy) / 4 + transfer = Math.floor(Math.min(transfer, (px.transfer + n.transfer) / 2)) + px.energy += transfer + n.energy -= transfer + } + + if (n.breath < px.breath) { + let transfer = (px.breath - n.breath) / 4 + transfer = Math.floor(Math.min(transfer, (px.transfer + n.transfer) / 2)) + px.breath -= transfer + n.breath += transfer + } else if (n.breath > px.breath) { + let transfer = (n.breath - px.breath) / 4 + transfer = Math.floor(Math.min(transfer, (px.transfer + n.transfer) / 2)) + px.breath += transfer + n.breath -= transfer + } + + if (n.waste !== undefined) { + if (n.inWaste) { + let transfer = Math.max(1, Math.floor(Math.min(px.waste / 4, (px.transfer + n.transfer) / 2))) + if (px.waste >= transfer) { + px.waste -= transfer + n.waste += transfer + } + } else { + if (n.waste < px.waste) { + let transfer = Math.max(1, Math.min((px.waste - n.waste) / 4, (px.transfer + n.transfer) / 2)) + px.waste -= transfer + n.waste += transfer + } else if (n.waste > px.waste) { + let transfer = Math.max(1, Math.min((n.waste - px.waste) / 4, (px.transfer + n.transfer) / 2)) + px.waste += transfer + n.waste -= transfer + } + } + } + }) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "sugar_water", "sugar_water"], + tempLow: -2, + stateLow: ["ice", "ice", "sugar_ice", "sugar_ice"], + state: "solid", + density: 1010, + category: "structural", + breakInto: ["sugar_water", "sugar_water", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 }, + sugar: undefined, + sugar_water: undefined, + }, + movable: false +} + +elements.neurocell = { // powers up venas + color: ["#5e5fa8"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 50, + cd: 1 + }, + conduct: 1, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + px.cd-- + if (px.cd < 1) { + px.cd = 20 + px.charge = 1 + } + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "sugar_water", "sugar_water"], + tempLow: -2, + stateLow: ["ice", "ice", "sugar_ice", "sugar_ice"], + state: "solid", + density: 1010, + category: "structural", + breakInto: ["sugar_water", "sugar_water", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 }, + sugar: undefined, + sugar_water: undefined, + }, + movable: false +} + +elements.waste = { // urocyte excretes this + color: "#5f9102", + behavior: behaviors.LIQUID, + state: "liquid", + category: "waste", + stateHigh: "stench", + burn: 20, + isFood: true, + burnTime: 150, + burnInto: "stench", + tempHigh: 120, + stateLow: "slime_ice", + tempLow: 0, + density: 1465, + viscosity: 5000 +} + +elements.mucus = { // light protective layer + color: "#aff036", + behavior: [ + "XX|SA|XX", + "SA|DL%1|XX", + "XX AND M2|SA AND M1|XX AND M2" + ], + state: "liquid", + category: "protection", + stateHigh: "steam", + tempHigh: 120, + stateLow: "slime_ice", + tempLow: 0, + density: 1400, + viscosity: 5000 +} + +elements.toxic_mucus = { // toxic protective layer, eats bugs for energy + color: "#58046d", + behavior: [ + "XX|SA|XX", + "SA|DL%1|XX", + "XX AND M2|SA AND M1|XX AND M2" + ], + tick: (px) => { + const ns = getNeighbors(px) + energy = 0 + ns.forEach(n => { + if (["ant", "fly", "spider", "worm", "flea", "rat", "frog", "tadpole", "fish", "slug", "snail"].includes(n.element)) { + deletePixel(n.x, n.y) + energy++ + } else if (n.element == "mucotoxin" && energy > 0) { + energy-- + n.waste += 0.6 + n.energy += 3000 + } + }) + }, + state: "liquid", + category: "protection", + stateHigh: "steam", + tempHigh: 120, + stateLow: "slime_ice", + tempLow: 0, + density: 1400, + viscosity: 5000 +} + +elements.slimecoat = { // generates mucus + color: ["#5a4606"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 0 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + const ns = getNeighbors(px) + let change = (ns.length == 4) + if (change) { + ns.forEach(n => { + if (n.element == ("mucus" || "toxic_mucus" || "slimecoat")) { + change = false + } + }) + } + if (change) { + changePixel(px, "stem_cell") + return + } + if (isEmpty(px.x - 1, px.y)) { + createPixel("mucus", px.x - 1, px.y) + } + if (isEmpty(px.x + 1, px.y)) { + createPixel("mucus", px.x + 1, px.y) + } + if (isEmpty(px.x, px.y - 1)) { + createPixel("mucus", px.x, px.y - 1) + } + if (isEmpty(px.x, px.y + 1)) { + createPixel("mucus", px.x, px.y + 1) + } + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 250, + stateHigh: "steam", + state: "solid", + density: 1800, + insulate: true, + category: "protection", + breakInto: ["tin", "dna", "dna"], + movable: false +} + +elements.mucotoxin = { // generates toxic mucus + color: ["#5a2806"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + waste: 0, + transfer: 0 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + const ns = getNeighbors(px) + let change = (ns.length == 4) + if (change) { + ns.forEach(n => { + if (n.element == ("mucus" || "toxic_mucus" || "mucotoxin")) { + change = false + } + }) + } + if (isEmpty(px.x - 1, px.y)) { + createPixel("toxic_mucus", px.x - 1, px.y) + } + if (isEmpty(px.x + 1, px.y)) { + createPixel("toxic_mucus", px.x + 1, px.y) + } + if (isEmpty(px.x, px.y - 1)) { + createPixel("toxic_mucus", px.x, px.y - 1) + } + if (isEmpty(px.x, px.y + 1)) { + createPixel("toxic_mucus", px.x, px.y + 1) + } + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 250, + stateHigh: "molten_tin", + state: "solid", + density: 1800, + insulate: true, + category: "protection", + breakInto: ["tin", "dna", "dna"], + movable: false +} + +elements.carapace = { // heat-resistant, cancer/infection proof shell + color: ["#46065a"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 0 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (pixel) => { + if (getNeighbors(pixel).length == 4) { changePixel(pixel, "stem_cell"); return } + baseCellTick(pixel) + doDefaults(pixel) + if (!isEmpty(pixel.x, pixel.y - 1, true)) { // Everything after this in the tick function is from biology.js, make sure to check it out too! + var hitPixel = pixelMap[pixel.x][pixel.y - 1] + if (elements[hitPixel.element].isCell != true && Math.random() > 0.5) { + if (hitPixel.temp > pixel.temp) { + hitPixel.temp-- + pixel.temp++ + } + } + } + if (!isEmpty(pixel.x, pixel.y + 1, true)) { + var hitPixel = pixelMap[pixel.x][pixel.y + 1] + if (elements[hitPixel.element].isCell != true && Math.random() > 0.5) { + if (hitPixel.temp > pixel.temp) { + hitPixel.temp-- + pixel.temp++ + } + } + } + if (!isEmpty(pixel.x - 1, pixel.y, true)) { + var hitPixel = pixelMap[pixel.x - 1][pixel.y] + if (elements[hitPixel.element].isCell != true && Math.random() > 0.5) { + if (hitPixel.temp > pixel.temp) { + hitPixel.temp-- + pixel.temp++ + } + } + } + if (!isEmpty(pixel.x + 1, pixel.y, true)) { + var hitPixel = pixelMap[pixel.x + 1][pixel.y] + if (elements[hitPixel.element].isCell != true && Math.random() > 0.5) { + if (hitPixel.temp > pixel.temp) { + hitPixel.temp-- + pixel.temp++ + } + } + } + doDefaults(pixel); + if (pixel.temp > 250) { + changePixel(pixel, "molten_tin", 250) + } + }, + tempHigh: 250, + stateHigh: "steam", + state: "solid", + density: 1800, + insulate: true, + category: "protection", + breakInto: ["tin", "dna", "dna"], + movable: false +} + +elements.phagocyte = { // turns cancer and infection into stem cells + color: ["#a3d9a6"], + behavior: behaviors.WALL, + noMix: true, + properties: { + energy: 300, + breath: 300, + transfer: 0 + }, + isCell: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + if (Math.random() < 0.35) { + const coords = circleCoords(px.x, px.y, 3) + coords.forEach(coord => { + if (!isEmpty(coord.x, coord.y)) { + const n = pixelMap[coord.x][coord.y] + if (n.element === "infection" || n.element === "cancer" || n.element === "poison") { + if (Math.random() < 0.35) { + changePixel(n, "stem_cell") + } + } + } + }) + } + baseCellTick(px) + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "sugar", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "sugar_ice", "sugar_ice"], + state: "solid", + density: 1010, + category: "protection", + breakInto: ["dna", "sugar", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem2: "stem_cell", chance: 0.055 }, + infection: { elem2: "stem_cell", chance: 0.075 }, + poison: { elem2: "stem_cell", chance: 0.025 }, + sugar: undefined, + sugar_water: undefined, + }, + movable: false +} + +elements.stem_cell = { // turns into the first cell it touches + color: ["#c0c0c0"], + behavior: behaviors.LIQUID, + noMix: true, + hoverStat: function (px) { + return `E:${px.energy} B:${px.breath}` + }, + tick: (px) => { + const ns = getNeighbors(px) + if (ns.length > 0) { + const elem = ns[Math.floor(Math.random() * ns.length)].element + if (elements[elem].isCell && elem !== "phagocyte") { + changePixel(px, elem) + } + } + doDefaults(px) + }, + tempHigh: 102, + stateHigh: ["steam", "steam", "sugar", "sugar"], + tempLow: -2, + stateLow: ["ice", "ice", "sugar_ice", "sugar_ice"], + state: "solid", + density: 1010, + category: "structural", + breakInto: ["dna", "sugar", "dna", "dna"], + reactions: { + ...elements.cell.reactions, + cancer: { elem1: "cancer", chance: 0.005 }, + sugar: undefined, + sugar_water: undefined, + } +} + +elements.cancer.reactions.chlorocyte = { elem2: "cancer", chance: 0.005 } +elements.cancer.reactions.respira = { elem2: "cancer", chance: 0.005 } +elements.cancer.reactions.neurocell = { elem2: "cancer", chance: 0.005 } +elements.cancer.reactions.vena = { elem2: "cancer", chance: 0.005 } +elements.cancer.reactions.fermentocyte = { elem2: "cancer", chance: 0.005 } +elements.cancer.reactions.root = { elem2: "cancer", chance: 0.005 } +elements.cancer.reactions.lipocyte = { elem2: "cancer", chance: 0.005 } +elements.cancer.reactions.slimecoat = { elem2: "cancer", chance: 0.005 } +elements.cancer.reactions.mucotoxin = { elem2: "cancer", chance: 0.005 } +elements.cancer.reactions.aerocyte = { elem2: "cancer", chance: 0.005 } +elements.cancer.reactions.urocyte = { elem2: "cancer", chance: 0.005 } + +elements.infection.reactions.chlorocyte = { elem2: "infection", chance: 0.0015 } +elements.infection.reactions.respira = { elem2: "infection", chance: 0.0015 } +elements.infection.reactions.neurocell = { elem2: "infection", chance: 0.0015 } +elements.infection.reactions.vena = { elem2: "infection", chance: 0.0015 } +elements.infection.reactions.fermentocyte = { elem2: "infection", chance: 0.0015 } +elements.infection.reactions.lipocyte = { elem2: "infection", chance: 0.0015 } +elements.infection.reactions.root = { elem2: "infection", chance: 0.0015 } +elements.infection.reactions.slimecoat = { elem2: "infection", chance: 0.0015 } +elements.infection.reactions.mucotoxin = { elem2: "infection", chance: 0.0015 } +elements.infection.reactions.aerocyte = { elem2: "infection", chance: 0.0015 } +elements.infection.reactions.urocyte = { elem2: "infection", chance: 0.0015 } + +elements.ant.reactions.waste = { elem2: null, chance: 0.035, func: behaviors.FEEDPIXEL } \ No newline at end of file