diff --git a/mods/aChefsDream.js b/mods/aChefsDream.js index 6269b075..7d9ea2c2 100644 --- a/mods/aChefsDream.js +++ b/mods/aChefsDream.js @@ -127,6 +127,41 @@ Changelog (v1.2) - added cream of tartar - added wine - added corn syrup + + + +Changelog (v1.3) + - added shrimp + - added coconuts + - added coconut stems + - added coconut leaves + - added coconut tree tops + - added coconut milk and coconut juice + - added cut coconuts + - salmon and tuna meats no longer melt + - added knife description + - added lemons and related stuff + - lemons + - lemon wood + - lemon branches + - lemon leaves + - lemon juice + - made by smashing lemons + - lemon seeds + - lemon slices + - made by cutting lemons + - lemon zest + - byproduct of cutting lemons + - lemon marmalade can now be made by mixing lemon slices or lemon zest with sugar + - added carrots + - added carrot seeds and leaves + - added carrot juice + - added dry icing + + + +Changelog (v1.3.1) + - added lemonade */ /* @@ -150,6 +185,8 @@ elements.knife = { changePixel(pixel, cutInto) }, category:"tools", + canPlace: false, + desc: "Use on pixels to cut them, if possible." } elements.chicken = { @@ -912,13 +949,25 @@ elements.icing_sugar = { elements.icing = { color: "#fefefb", - behavior: behaviors.STURDYPOWDER, + behavior: behaviors.LIQUID, onMix: function(icing_sugar1, icing_sugar2) { if ((shiftDown && Math.random() < 0.2) || (elements[icing_sugar2.element].id === elements.icing_sugar.id && Math.random() < 0.25)) { changePixel(icing_sugar1,"icing") } }, - viscosity: 1.5, + tempHigh: 45, + stateHigh: ["dry_icing"], + stateLowColorMultiplier: 0.97, + category: "food", + isFood: true, + state: "solid", + density: 959.97, + viscosity: 9000, +}; + +elements.dry_icing = { + color: "#fffefa", + behavior: behaviors.STURDYPOWDER, tempHigh: 1000, stateHigh: ["smoke","smoke","smoke","steam","steam","calcium"], stateLowColorMultiplier: 0.97, @@ -926,6 +975,7 @@ elements.icing = { isFood: true, state: "solid", density: 959.97, + viscosity: 9000, }; elements.cream.reactions.baked_batter = {elem2: "cake" } @@ -1370,18 +1420,18 @@ elements.smoked_salmon = { state: "solid", temp:55, tempHigh: 600, - stageHigh: ["ash", "smoke"], + stateHigh: ["ash", "smoke"], isFood: true, } -elements.steaned_salmon = { +elements.steamed_salmon = { color: ["#BB7B4B", "#B07B54"], behavior: behaviors.STURDYPOWDER, category: "food", state: "solid", temp:60, tempHigh: 600, - stageHigh: ["ash", "smoke"], + stateHigh: ["ash", "smoke"], isFood: true, } @@ -1392,7 +1442,7 @@ elements.boiled_salmon = { state: "solid", temp:70, tempHigh: 600, - stageHigh: ["ash", "smoke"], + stateHigh: ["ash", "smoke"], isFood: true, } @@ -1403,7 +1453,7 @@ elements.fried_salmon = { state: "solid", temp:70, tempHigh: 600, - stageHigh: ["ash", "smoke"], + stateHigh: ["ash", "smoke"], isFood: true, } @@ -1443,7 +1493,7 @@ elements.smoked_tuna = { state: "solid", temp:55, tempHigh: 600, - stageHigh: ["ash", "smoke"], + stateHigh: ["ash", "smoke"], isFood: true, } @@ -1454,7 +1504,7 @@ elements.steamed_tuna = { state: "solid", temp:60, tempHigh: 600, - stageHigh: ["ash", "smoke"], + stateHigh: ["ash", "smoke"], isFood: true, } @@ -1465,7 +1515,7 @@ elements.boiled_tuna = { state: "solid", temp:70, tempHigh: 600, - stageHigh: ["ash", "smoke"], + stateHigh: ["ash", "smoke"], isFood: true, } @@ -1476,7 +1526,7 @@ elements.fried_tuna = { state: "solid", temp:70, tempHigh: 600, - stageHigh: ["ash", "smoke"], + stateHigh: ["ash", "smoke"], isFood: true, } @@ -1655,6 +1705,7 @@ elements.grape_juice = { "clay_soil": { elem1: null, elem2: "clay" }, "seltzer": { elem1: "soda", elem2: "foam" }, "carbon_dioxide": { elem1: "soda", elem2: "foam" }, + "milk": { elem1: "fruit_milk", elem2: "fruit_milk" }, "yeast": { elem1: ["wine","wine","wine","wine","wine","wine","wine","wine","wine","wine","wine","wine","wine","wine","wine","wine","wine","wine","wine","cream_of_tartar"], elem2: null, chance:80 }, }, tempHigh: 160, @@ -1665,6 +1716,7 @@ elements.grape_juice = { state: "liquid", density: 1054, stain: 0.05, + hidden: true, isFood: true }; @@ -1677,6 +1729,7 @@ elements.cream_of_tartar = { stateHigh: "caramel", density: 1500, isFood: true, + hidden: true, reaction: { "sugar_water": {elem2: "corn_syrup", elem1: null, tempMin: 110} } @@ -1690,7 +1743,9 @@ elements.wine = { tempHigh: 100, stateHigh: "steam", isFood: true, - density: 1200, + density: 1000, + hidden: true, + tempLow: 0 } elements.corn_syrup = { @@ -1701,5 +1756,646 @@ elements.corn_syrup = { tempHigh: 100, stateHigh: "caramel", isFood: true, + hidden: true, viscosity: 10000 } + +elements.shrimp = { + color: ["#EE5422", "#E9683C", "#F3583F", "#EDA270"], + behavior: [ + "SW:water,salt_water,sugar_water,dirty_water,seltzer,pool_water,primordial_soup%14|M2%7.5 AND SW:water,salt_water,sugar_water,dirty_water,seltzer,pool_water,primordial_soup%5|SW:water,salt_water,sugar_water,dirty_water,seltzer,pool_water,primordial_soup%14", + "SW:water,salt_water,sugar_water,dirty_water,seltzer,pool_water,primordial_soup%14|FX%20|SW:water,salt_water,sugar_water,dirty_water,seltzer,pool_water,primordial_soup%14", + "M2 AND SW:water,salt_water,sugar_water,dirty_water,seltzer,pool_water,primordial_soup%15|M1|M2 AND SW:water,salt_water,sugar_water,dirty_water,seltzer,pool_water,primordial_soup%15", + ], + category: "life", + state: "solid", + reactions: { + "algae": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL }, + "plant": { elem2:null, chance:0.125, func:behaviors.FEEDPIXEL }, + "fly": { elem2:null, chance:0.4, func:behaviors.FEEDPIXEL }, + "firefly": { elem2:null, chance:0.6, func:behaviors.FEEDPIXEL }, + "worm": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL }, + "tadpole": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL }, + "oxygen": { elem2:"carbon_dioxide", chance:0.5 }, + "dead_bug": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL }, + "broth": { elem2:"water", chance:0.2, func:behaviors.FEEDPIXEL }, + "slug": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL }, + "herb": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL }, + "lettuce": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL }, + "dead_plant": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL }, + "lichen": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL }, + "yeast": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL }, + "yogurt": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL }, + "tea": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL }, + "meat": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL }, + "rotten_meat": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL }, + "cooked_meat": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL }, + "yolk": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL }, + "cell": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL }, + "crumb": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL }, + }, +} + + +elements.coconut_seed = { + color: "#7a603d", + tick: function(pixel) { + if (Math.random() < 0.1 && pixel.age > 50 && pixel.temp < 100) { + if (!outOfBounds(pixel.x,pixel.y+1)) { + var dirtPixel = pixelMap[pixel.x][pixel.y+1]; + if (dirtPixel.element === "dirt" || dirtPixel.element === "mud" || dirtPixel.element === "sand" || dirtPixel.element === "wet_sand" || dirtPixel.element === "clay_soil" || dirtPixel.element === "mycelium") { + changePixel(dirtPixel,"root"); + } + } + if (isEmpty(pixel.x,pixel.y-1) && pixel.height < 7) { + movePixel(pixel,pixel.x,pixel.y-1); + createPixel(Math.random() > 0.5 ? "coconut_stem" : "coconut_stem",pixel.x,pixel.y+1); + + pixel.height++ + } + } + else if (pixel.age > 150 && pixel.height > 6 && Math.random() < 0.1) { + changePixel(pixel,"coconut_tree_top"); + } + pixel.age++; + doDefaults(pixel); + }, + properties: { + "age":0, + "height": 0 + }, + tempHigh: 100, + stateHigh: "dead_plant", + tempLow: -2, + stateLow: "frozen_plant", + burn: 65, + burnTime: 15, + category: "life", + state: "solid", + density: 1500, + cooldown: defaultCooldown, + seed: true, + behavior: [ + "XX|XX|XX", + "XX|XX|XX", + "XX|M1|XX", + ], +}; + +elements.coconut_stem = { + color: "#8f6c3f", + behavior: behaviors.WALL, + tempHigh: 400, + stateHigh: ["ember","charcoal","fire","fire","fire"], + category: "solids", + burn: 5, + burnTime: 300, + burnInto: ["ember","charcoal","fire"], + state: "solid", + hardness: 0.15, + breakInto: "sawdust", + breakIntoColor: ["#dba66e","#cc8a64"], + hidden: true +} +elements.coconut_tree_top = { + color: "#8f6c3f", + behavior: behaviors.WALL, + tempHigh: 400, + stateHigh: ["ember","charcoal","fire","fire","fire"], + category: "solids", + burn: 5, + burnTime: 300, + burnInto: ["ember","charcoal","fire"], + state: "solid", + hardness: 0.15, + breakInto: "sawdust", + breakIntoColor: ["#dba66e","#cc8a64"], + properties:{ + "leftleaves": 0, + "rightleaves": 0, + }, + hidden: true, + tick: function(pixel) { + if (Math.random() < 0.1 && pixel.age > 50 && pixel.temp < 100 && pixel.rightleaves == 0) { + if (isEmpty(pixel.x+1,pixel.y)) { + createPixel(Math.random() > 0.5 ? "coconut_leaves" : "coconut_leaves",pixel.x+1,pixel.y); + + pixel.rightleaves++ + } + } + if (Math.random() < 0.1 && pixel.age > 50 && pixel.temp < 100 && pixel.rightleaves == 1) { + if (isEmpty(pixel.x+2,pixel.y)) { + createPixel(Math.random() > 0.5 ? "coconut_leaves" : "coconut_leaves",pixel.x+2,pixel.y); + + pixel.rightleaves++ + } + } + if (Math.random() < 0.1 && pixel.age > 50 && pixel.temp < 100 && pixel.rightleaves == 2) { + if (isEmpty(pixel.x+3,pixel.y)) { + createPixel(Math.random() > 0.5 ? "coconut_leaves" : "coconut_leaves",pixel.x+3,pixel.y); + + pixel.rightleaves++ + } + } + if (Math.random() < 0.1 && pixel.age > 50 && pixel.temp < 100 && pixel.rightleaves == 3) { + if (isEmpty(pixel.x+4,pixel.y+1)) { + createPixel(Math.random() > 0.5 ? "coconut_leaves" : "coconut_leaves",pixel.x+4,pixel.y+1); + + pixel.rightleaves++ + } + } + + + if (Math.random() < 0.1 && pixel.age > 50 && pixel.temp < 100 && pixel.leftleaves == 0) { + if (isEmpty(pixel.x-1,pixel.y)) { + createPixel(Math.random() > 0.5 ? "coconut_leaves" : "coconut_leaves",pixel.x-1,pixel.y); + + pixel.leftleaves++ + } + } + if (Math.random() < 0.1 && pixel.age > 50 && pixel.temp < 100 && pixel.leftleaves == 1) { + if (isEmpty(pixel.x-2,pixel.y)) { + createPixel(Math.random() > 0.5 ? "coconut_leaves" : "coconut_leaves",pixel.x-2,pixel.y); + + pixel.leftleaves++ + } + } + if (Math.random() < 0.1 && pixel.age > 50 && pixel.temp < 100 && pixel.leftleaves == 2) { + if (isEmpty(pixel.x-3,pixel.y)) { + createPixel(Math.random() > 0.5 ? "coconut_leaves" : "coconut_leaves",pixel.x-3,pixel.y); + + pixel.leftleaves++ + } + } + if (Math.random() < 0.1 && pixel.age > 50 && pixel.temp < 100 && pixel.leftleaves == 3) { + if (isEmpty(pixel.x-4,pixel.y+1)) { + createPixel(Math.random() > 0.5 ? "coconut_leaves" : "coconut_leaves",pixel.x-4,pixel.y+1); + + pixel.leftleaves++ + } + } + + + if (Math.random() < 0.1 && pixel.age > 70 && pixel.temp < 100 && pixel.leftleaves > 0 && pixel.rightleaves > 0) { + if (isEmpty(pixel.x+1,pixel.y+1)) { + createPixel(Math.random() > 0.5 ? "coconut" : "coconut",pixel.x+1,pixel.y+1); + } + } + if (Math.random() < 0.1 && pixel.age > 70 && pixel.temp < 100 && pixel.leftleaves > 0 && pixel.rightleaves > 0) { + if (isEmpty(pixel.x-1,pixel.y+1)) { + createPixel(Math.random() > 0.5 ? "coconut" : "coconut",pixel.x-1,pixel.y+1); + } + } + pixel.age++; + doDefaults(pixel); +}, +} +elements.coconut_leaves = { + color: ["#569923","#5ea12b"], + reactions: { + "vinegar": { elem1:"dead_plant", elem2:null, chance:0.035 }, + "baking_soda": { elem1:"dead_plant", elem2:null, chance:0.01 }, + "bleach": { elem1:"dead_plant", elem2:null, chance:0.05 }, + "alcohol": { elem1:"dead_plant", elem2:null, chance:0.035 } + }, + category:"life", + tempHigh: 100, + stateHigh: "dead_plant", + tempLow: -1.66, + stateLow: "frozen_plant", + burn:65, + burnTime:60, + burnInto: "dead_plant", + breakInto: "dead_plant", + state: "solid", + density: 1050, + hidden: true +} +elements.coconut = { + color: "#6e4621", + behavior: [ + "ST:coconut_tree_top|ST:coconut_leaves|ST:coconut_tree_top", + "ST:coconut_stem|XX|ST:coconut_stem", + "M2|M1|M2", + ], + reactions: { + "vinegar": { elem1:"dead_plant", elem2:null, chance:0.035 }, + "baking_soda": { elem1:"dead_plant", elem2:null, chance:0.01 }, + "bleach": { elem1:"dead_plant", elem2:null, chance:0.05 }, + "alcohol": { elem1:"dead_plant", elem2:null, chance:0.035 } + }, + category:"food", + tempHigh: 100, + stateHigh: "dead_plant", + tempLow: -1.66, + stateLow: "frozen_plant", + burn:65, + burnTime:60, + burnInto: "dead_plant", + breakInto: "coconut_milk", + cutInto: ["cut_coconut"], + state: "solid", + density: 1050, +} + +elements.coconut_milk = { + color: "#fffcf2", + behavior: behaviors.LIQUID, + reactions: { + "melted_chocolate": { elem1:"chocolate_milk", elem2:null }, + "chocolate": { elem1:"chocolate_milk", elem2:"melted_chocolate", chance:0.05 }, + "coffee_ground": { elem1:"chocolate_milk", chance:0.05 }, + "juice": { elem1:"fruit_milk", elem2:null, chance:0.05 }, + "soda": { elem1:"pilk", elem2:null, chance:0.1 }, + "yolk": { elem1:"eggnog", elem2:null, chance:0.1 }, + "dirt": { elem1: null, elem2: "mud" }, + "sand": { elem1: null, elem2: "wet_sand" }, + "clay_soil": { elem1: null, elem2: "clay" }, + "caramel": { color1:"#C8B39A", elem2:null, chance:0.05 }, + "sugar": { elem2:null, chance:0.005}, + }, + tempLow: 0, + stateLow: "ice_cream", + stateLowColorMultiplier: [0.97,0.93,0.87], + tempHigh: 93, + stateHigh: "yogurt", + viscosity: 1.5, + category: "liquids", + state: "liquid", + density: 1036.86, + isFood: true +} + +elements.tea.reactions.coconut_milk = { elem2:null, color1:"#ad8955", chance:0.005} +elements.coffee.reactions.coconut_milk = { elem2:"foam", color1:"#856545", chance:0.005} + +elements.cut_coconut = { + color: "#fff2cf", + behavior: [ + "XX|XX|XX", + "XX|XX|XX", + "M2|M1|M2", + ], + reactions: { + "vinegar": { elem1:"dead_plant", elem2:null, chance:0.035 }, + "baking_soda": { elem1:"dead_plant", elem2:null, chance:0.01 }, + "bleach": { elem1:"dead_plant", elem2:null, chance:0.05 }, + "alcohol": { elem1:"dead_plant", elem2:null, chance:0.035 } + }, + category:"food", + tempHigh: 100, + stateHigh: "dead_plant", + tempLow: -1.66, + stateLow: "frozen_plant", + burn:65, + burnTime:60, + burnInto: "dead_plant", + breakInto: "coconut_juice", + state: "solid", + density: 1050, + hidden: true, +} + +elements.coconut_juice = { + color: "#e9ebe4", + behavior: behaviors.LIQUID, + reactions: { + "dirt": { elem1: null, elem2: "mud" }, + "sand": { elem1: null, elem2: "wet_sand" }, + "clay_soil": { elem1: null, elem2: "clay" }, + "caramel": { color1:"#C8B39A", elem2:null, chance:0.05 }, + }, + tempLow: 0, + tempHigh: 93, + stateHigh: ["sugar","steam"], + viscosity: 1.5, + category: "liquids", + state: "liquid", + density: 1036.86, + hidden: true, + isFood: true +} + +elements.lemon_wood = { + color: "#786531", + behavior: behaviors.WALL, + tempHigh: 400, + stateHigh: ["ember","charcoal","fire","fire","fire"], + category: "solids", + burn: 5, + burnTime: 300, + burnInto: ["ember","charcoal","fire"], + state: "solid", + hardness: 0.15, + breakInto: "sawdust", + breakIntoColor: ["#dba66e","#cc8a64"], +} +elements.lemon_branch = { + color: "#786531", + behavior: [ + "CR:lemon_leaves,lemon_branch%2|CR:lemon_leaves,lemon_leaves,lemon_leaves,lemon_branch%2|CR:lemon_leaves,lemon_branch%2", + "XX|XX|XX", + "XX|XX|XX", + ], + tempHigh: 100, + stateHigh: "lemon_wood", + tempLow: -30, + stateLow: "lemon_wood", + category: "life", + burn: 40, + burnTime: 50, + burnInto: ["sap","ember","charcoal"], + hidden: true, + state: "solid", + density: 1500, + hardness: 0.15, + breakInto: ["sap","sawdust"], + hidden: true, +} +elements.lemon_leaves = { + color: ["#42b336","#46a83b"], + behavior: [ + "XX|XX|XX", + "XX|XX|XX", + "XX|CR:lemon%0.15|XX", + ], + reactions: { + "vinegar": { elem1:"dead_plant", elem2:null, chance:0.035 }, + "baking_soda": { elem1:"dead_plant", elem2:null, chance:0.01 }, + "bleach": { elem1:"dead_plant", elem2:null, chance:0.05 }, + "alcohol": { elem1:"dead_plant", elem2:null, chance:0.035} + }, + category:"life", + tempHigh: 100, + stateHigh: "dead_plant", + tempLow: -1.66, + stateLow: "frozen_plant", + burn:65, + burnTime:60, + burnInto: "dead_plant", + breakInto: "dead_plant", + state: "solid", + density: 1050, + seed: "lemon_seed", + hidden: true +} +elements.lemon = { + color: ["#dbd937","#e0dd28"], + behavior: behaviors.POWDER, + reactions: { + "vinegar": { elem1:"dead_plant", elem2:null, chance:0.035 }, + "baking_soda": { elem1:"dead_plant", elem2:null, chance:0.01 }, + "bleach": { elem1:"dead_plant", elem2:null, chance:0.05 }, + "alcohol": { elem1:"dead_plant", elem2:null, chance:0.035 }, + "sugar": { elem1:"marmalade", elem2:null, color1:"#e0bf2b", chance:0.35 } + }, + category:"food", + tempHigh: 100, + stateHigh: "dead_plant", + tempLow: -1.66, + stateLow: "frozen_plant", + burn:65, + burnTime:60, + burnInto: "dead_plant", + breakInto: "lemon_juice", + state: "solid", + density: 1050, + isFood: true, + cutInto: ["lemon_zest","lemon_slice","lemon_slice","lemon_slice","lemon_slice"], +} + +elements.lemon_juice = { + color: "#e0d358", + behavior: behaviors.LIQUID, + category: "liquids", + tempHigh: 100, + stateHigh: ["steam","sugar"], + burn: 70, + burnTime: 300, + burnInto: ["steam", "smoke"], + state: "liquid", + density: 825, + hidden: true, + temp: 30, + hidden: true, + tempLow: 0, + reactions: { + "sugar": {elem1:"lemonade", elem2: "null", chance:0.35} + } +}; + +elements.lemonade = { + color: "#fff378", + behavior: behaviors.LIQUID, + category: "liquids", + tempHigh: 100, + stateHigh: ["steam","sugar"], + burn: 70, + burnTime: 300, + burnInto: ["steam", "smoke"], + state: "liquid", + density: 825, + hidden: true, + temp: 30, + hidden: true, + tempLow: 0 +}; + +elements.lemon_zest = { + color: "#dbc535", + behavior: behaviors.POWDER, + category:"food", + tempHigh: 100, + stateHigh: ["sugar","steam"], + burn:65, + burnTime:60, + burnInto: "dead_plant", + state: "solid", + density: 1050, + hidden: true, + reactions: { + "sugar": { elem1:"marmalade", elem2:null, color1:"#e0bf2b", chance:0.35 } + }, +} + +elements.lemon_slice = { + color: "#ebe431", + behavior: behaviors.STURDYPOWDER, + category:"food", + tempHigh: 100, + stateHigh: ["sugar","steam"], + burn:65, + burnTime:60, + burnInto: "dead_plant", + breakInto: "lemon_juice", + state: "solid", + density: 1050, + hidden: true, + reactions: { + "sugar": { elem1:"marmalade", elem2:null, color1:"#e0bf2b", chance:0.35 } + }, +} + +elements.lemon_seed = { + color: "#854610", + tick: function(pixel) { + if (isEmpty(pixel.x,pixel.y+1)) { + movePixel(pixel,pixel.x,pixel.y+1); + } + else { + if (Math.random() < 0.02 && pixel.age > 50 && pixel.temp < 100) { + if (!outOfBounds(pixel.x,pixel.y+1)) { + var dirtPixel = pixelMap[pixel.x][pixel.y+1]; + if (dirtPixel.element === "dirt" || dirtPixel.element === "mud" || dirtPixel.element === "sand" || dirtPixel.element === "wet_sand" || dirtPixel.element === "clay_soil" || dirtPixel.element === "mycelium") { + changePixel(dirtPixel,"root"); + } + } + if (isEmpty(pixel.x,pixel.y-1)) { + movePixel(pixel,pixel.x,pixel.y-1); + createPixel(Math.random() > 0.5 ? "lemon_wood" : "lemon_branch",pixel.x,pixel.y+1); + } + } + else if (pixel.age > 1000) { + changePixel(pixel,"lemon_wood"); + } + pixel.age++; + } + doDefaults(pixel); + }, + properties: { + "age":0 + }, + tempHigh: 100, + stateHigh: "dead_plant", + tempLow: -2, + stateLow: "frozen_plant", + burn: 65, + burnTime: 15, + category: "life", + state: "solid", + density: 1500, + cooldown: defaultCooldown, + seed: true, + behavior: [ + "XX|XX|XX", + "XX|FX%10|XX", + "XX|M1|XX", + ], +}; + + +elements.carrot_seed = { + color: "#b08d35", + tick: function(pixel) { + if (Math.random() < 0.1 && pixel.age > 100 && pixel.temp < 100 && pixel.leafgrown == true && pixel.growthpixel == 0) { + if (!outOfBounds(pixel.x,pixel.y+1)) { + var randomNumber1 = Math.round(Math.random()) + pixel.growthpixel = pixel.growthpixel+randomNumber1 + var dirtPixel = pixelMap[pixel.x][pixel.y+1]; + if (dirtPixel.element === "dirt" || dirtPixel.element === "mud" || dirtPixel.element === "sand" || dirtPixel.element === "wet_sand" || dirtPixel.element === "clay_soil" || dirtPixel.element === "mycelium") { + deletePixel(pixel.x,pixel.y+1); + movePixel(pixel,pixel.x,pixel.y+1); + createPixel("carrot_leaves",pixel.x,pixel.y-1); + pixel.growthpixel++; + } + } + + } + if (Math.random() < 0.1 && pixel.age > 100 && pixel.temp < 100 && pixel.leafgrown == true && pixel.growthpixel > 0 && pixel.growthpixel < 4) { + if (!outOfBounds(pixel.x,pixel.y+1)) { + var dirtPixel = pixelMap[pixel.x][pixel.y+1]; + if (dirtPixel.element === "dirt" || dirtPixel.element === "mud" || dirtPixel.element === "sand" || dirtPixel.element === "wet_sand" || dirtPixel.element === "clay_soil" || dirtPixel.element === "mycelium") { + deletePixel(pixel.x,pixel.y+1); + movePixel(pixel,pixel.x,pixel.y+1); + createPixel("carrot",pixel.x,pixel.y-1); + pixel.growthpixel++; + } + } + + } + if (!isEmpty(pixel.x,pixel.y+1) && Math.random() > 0.95 && isEmpty(pixel.x-1,pixel.y-1) && isEmpty(pixel.x+1,pixel.y-1) && pixel.leafgrown == false) { + createPixel("carrot_leaves",pixel.x-1,pixel.y-1); + createPixel("carrot_leaves",pixel.x+1,pixel.y-1); + pixel.leafgrown++ + } + else if (pixel.age > 150 && pixel.growthpixel == 4 && Math.random() < 0.1) { + changePixel(pixel,"carrot"); + } + pixel.age++; + doDefaults(pixel); + }, + properties: { + "age":0, + "growthpixel": 0, + "leafgrown": false + }, + tempHigh: 100, + stateHigh: "dead_plant", + tempLow: -2, + stateLow: "frozen_plant", + burn: 65, + burnTime: 15, + category: "life", + state: "solid", + density: 1500, + cooldown: defaultCooldown, + seed: true, + behavior: [ + "XX|XX|XX", + "XX|XX|XX", + "XX|M1|XX", + ], +}; +elements.carrot_leaves = { + color: ["#61cc3d","#58c234"], + behavior: behaviors.WALL, + reactions: { + "vinegar": { elem1:"dead_plant", elem2:null, chance:0.035 }, + "baking_soda": { elem1:"dead_plant", elem2:null, chance:0.01 }, + "bleach": { elem1:"dead_plant", elem2:null, chance:0.05 }, + "alcohol": { elem1:"dead_plant", elem2:null, chance:0.035} + }, + category:"life", + tempHigh: 100, + stateHigh: "dead_plant", + tempLow: -1.66, + stateLow: "frozen_plant", + burn:65, + burnTime:60, + burnInto: "dead_plant", + breakInto: "dead_plant", + state: "solid", + density: 1050, + seed: "carrot_seed", + hidden: true +} +elements.carrot = { + color: "#e39919", + behavior: behaviors.STURDYPOWDER, + category:"food", + tempHigh: 100, + stateHigh: ["steam"], + burn:65, + burnTime:60, + burnInto: "dead_plant", + breakInto: "carrot_juice", + state: "solid", + density: 1050, + hidden: true, +} + +elements.carrot_juice = { + color: "#f5a742", + behavior: behaviors.LIQUID, + category: "liquids", + tempHigh: 100, + stateHigh: ["steam","sugar"], + burn: 70, + tempLow: 0, + burnTime: 300, + burnInto: ["steam", "smoke"], + state: "liquid", + density: 825, + hidden: true, + temp: 30, +}; diff --git a/mods/a_mod_by_alice.js b/mods/a_mod_by_alice.js index b86c810f..fec50ee1 100644 --- a/mods/a_mod_by_alice.js +++ b/mods/a_mod_by_alice.js @@ -26,7 +26,7 @@ try { return Object.keys(object).find(key => object[key] === value); }; - //R.N.G. + //RNG //Random integer from 0 to n function randomIntegerFromZeroToValue(value) { @@ -47,6 +47,11 @@ try { return array[randomIndex]; }; + //Random 1 or -1 + function randomSign() { + return Math.random() < 0.5 ? 1 : -1 + }; + //Random integer from m to n function randomIntegerBetweenTwoValues(min,max) { if(min > max) { @@ -1146,7 +1151,7 @@ try { }; } - function changeSaturation(color,saturationChange,operationType="add",outputType="rgb",arrayType=null) { + function changeSaturation(color,saturationChange,operationType="add",outputType="rgb",arrayType=null,doRounding=true) { color = normalizeColorToHslObject(color,arrayType); //only {h,s,l} should exist now @@ -1189,14 +1194,14 @@ try { throw new Error("Operation must be \"add\", \"subtract\", \"multiply\", \"divide\", \"set\", \"min\", or \"max\""); }; - color.h = Math.round(color.h % 360); - color.s = Math.round(bound(color.s,0,100)); - color.l = Math.round(bound(color.l,0,100)); + color.h = doRounding ? Math.round(color.h % 360) : color.h % 360; + color.s = doRounding ? Math.round(bound(color.s,0,100)) : color.s,0,100; + color.l = doRounding ? Math.round(bound(color.l,0,100)) : color.l,0,100; return convertHslObjects(color,outputType) }; - function changeLuminance(color,luminanceChange,operationType="add",outputType="rgb",arrayType=null) { + function changeLuminance(color,luminanceChange,operationType="add",outputType="rgb",arrayType=null,doRounding=true) { color = normalizeColorToHslObject(color,arrayType); //only {h,s,l} should exist now @@ -1239,14 +1244,14 @@ try { throw new Error("Operation must be \"add\", \"subtract\", \"multiply\", \"divide\", \"set\", \"min\", or \"max\""); }; - color.h = Math.round(color.h % 360); - color.s = Math.round(bound(color.s,0,100)); - color.l = Math.round(bound(color.l,0,100)); + color.h = doRounding ? Math.round(color.h % 360) : color.h % 360; + color.s = doRounding ? Math.round(bound(color.s,0,100)) : color.s,0,100; + color.l = doRounding ? Math.round(bound(color.l,0,100)) : color.l,0,100; return convertHslObjects(color,outputType); }; - function changeHue(color,hueChange,operationType="add",outputType="rgb",arrayType=null) { + function changeHue(color,hueChange,operationType="add",outputType="rgb",arrayType=null,doRounding=true) { color = normalizeColorToHslObject(color,arrayType); //only {h,s,l} should exist now @@ -1289,9 +1294,9 @@ try { throw new Error("Operation must be \"add\", \"subtract\", \"multiply\", \"divide\", \"set\", \"min\", or \"max\""); }; - color.h = Math.round(color.h % 360); - color.s = Math.round(bound(color.s,0,100)); - color.l = Math.round(bound(color.l,0,100)); + color.h = doRounding ? Math.round(color.h % 360) : color.h % 360; + color.s = doRounding ? Math.round(bound(color.s,0,100)) : color.s,0,100; + color.l = doRounding ? Math.round(bound(color.l,0,100)) : color.l,0,100; return convertHslObjects(color,outputType); }; @@ -1322,6 +1327,12 @@ try { }; //Pixels + + function tryMoveAndReturnBlockingPixel(pixel,nx,ny,leaveBehind,force) { + if(outOfBounds(nx,ny)) { return false }; + if(isEmpty(nx,ny,false)) { return tryMove(pixel,nx,ny,leaveBehind,force) }; + return pixelMap[nx][ny] + }; function exposedToAir(pixel) { return (isEmpty(pixel.x+1,pixel.y) || isEmpty(pixel.x-1,pixel.y) || isEmpty(pixel.x,pixel.y+1) || isEmpty(pixel.x,pixel.y-1)); @@ -1727,6 +1738,69 @@ try { return returnPixel ? newPixel : true }; + function cloneArea(topLeftX,topLeftY,bottomRightX,bottomRightY,newTopLeftX,newTopLeftY,oldPixelHandling_PreClear1_OnlyReplace2_Ignore3=1,errorOnOutOfBounds=false) { + var results = {"created": 0, "replaced": 0, "deleted": 0, "skipped": 0, "skipped_OOB": 0}; + for(var x = topLeftX; x <= bottomRightX; x++) { + for(var y = topLeftY; y <= bottomRightY; y++) { + var relativeOffsetX = x - topLeftX; + var relativeOffsetY = y - topLeftY; + var newCoords = {"x": newTopLeftX+relativeOffsetX, "y": newTopLeftY+relativeOffsetY}; + var oldCoords = {"x": x, "y": y}; + var oldCoordsOOB = outOfBounds(oldCoords.x,oldCoords.y); + var newCoordsOOB = outOfBounds(newCoords.x,newCoords.y); + if(oldCoordsOOB || newCoordsOOB) { + if(errorOnOutOfBounds) { + var message; + if(oldCoordsOOB && !newCoordsOOB) { + message = "cloneArea: Source is or extends outside of the canvas." + } else if(!oldCoordsOOB && newCoordsOOB) { + message = "cloneArea: Destination is or extends outside of the canvas." + } else if(oldCoordsOOB && newCoordsOOB) { + message = "cloneArea: Source and destination are or extend outside of the canvas." + } else { + message = "cloneArea: ??? (Something has gone wrong with the OOB handling code.)" + }; + throw new Error(message) + } else { + results.skipped_OOB++; + continue + } + }; + if(isEmpty(newCoords.x,newCoords.y)) { + //Empty destination, full source + if(!(isEmpty(oldCoords.x,oldCoords.y))) { + clonePixel(pixelMap[oldCoords.x][oldCoords.y],newCoords.x,newCoords.y); + results.created++; + } + } else { + //Full destination, empty source + if(isEmpty(oldCoords.x,oldCoords.y)) { + //Delete the blocking pixel only if pre-clearing + if(oldPixelHandling_PreClear1_OnlyReplace2_Ignore3 == 1) { + deletePixel(newCoords.x,newCoords.y); + results.deleted++ + } else { + results.skipped++ + } + } + //Full destination, full source + else { + //Delete the blocking pixel if not ignoring (as for the above case, pre-clearing is not ignoring) + if(oldPixelHandling_PreClear1_OnlyReplace2_Ignore3 !== 3) { + deletePixel(newCoords.x,newCoords.y); + //Place the cloned pixel + clonePixel(pixelMap[oldCoords.x][oldCoords.y],newCoords.x,newCoords.y) + results.replaced++; + } else { + results.skipped++ + }; + } + } + } + }; + return results + }; + function getEmptyVonNeumannNeighbors(pixel) { var neighbors = []; var x = pixel.x; @@ -1845,6 +1919,32 @@ try { return true; }; + //Melt pixel + function meltPixel(pixel,changetemp=true) { + var info = elements[pixel.element]; + var result = info.stateHigh; + if (!result) { + return false + }; + if(result instanceof Array) { + result = result.filter(elementExists); + if(result.length == 0) { + return false; + }; + } else { + if(!(elementExists(result))) { + return false; + }; + }; + + while(result instanceof Array) { + result = randomChoice(result); + }; + + changePixel(pixel,result,changetemp); + return true; + }; + //Logic function xor(c1,c2) { @@ -2352,8 +2452,9 @@ color1 and color2 spread through striped paint like dye does with itself. col oldChangePixel = changePixel; changePixel = function(pixel,element,changetemp=true) { if(typeof(elements[element]) == "undefined") { + if(typeof(element) == "undefined" || element == "undefined") { return false }; if(doLog) { console.error(`Something tried to change a pixel of ${pixel.element} at (${pixel.x},${pixel.y}) to nonexistent element "${element}"`) }; - return false; + return false }; oldChangePixel(pixel,element,changetemp); }; @@ -3465,6 +3566,9 @@ color1 and color2 spread through striped paint like dye does with itself. col if(typeof(beforeFunction) === "function") { beforeFunction(pixel,x,y,radius,fire,smoke,power,damage); }; + if(!pixel || pixel.del || typeof(pixel) == "undefined" || isEmpty(coords[i].x,coords[i].y)) { + continue + }; if (info.hardness) { // lower damage depending on hardness(0-1) if (info.hardness < 1) { damage = damage * ((1 - info.hardness)*10); @@ -3771,8 +3875,41 @@ color1 and color2 spread through striped paint like dye does with itself. col //No changeTemp for fire=>smoke elements.fire.tick = function(pixel){ - behaviors.UL_UR_OPTIMIZED(pixel); - if (!pixel.del && settings.burn===0 && (pixelTicks-pixel.start > 70) && Math.random() < 0.1 ) { changePixel(pixel,"smoke",false) } + if (pixel.start === pixelTicks) {return} + if (pixel.charge && elements[pixel.element].behaviorOn) { + pixelTick(pixel) + } + var move1Spots = [ + [pixel.x, pixel.y-1], + [pixel.x+1, pixel.y-1], + [pixel.x-1, pixel.y-1], + ] + var moved = false; + for (var i = 0; i < move1Spots.length; i++) { + var coords = move1Spots[Math.floor(Math.random()*move1Spots.length)]; + coords = {x: coords[0], y: coords[1]}; + if(!isEmpty(coords.x,coords.y,true) && pixelMap[coords.x]?.[coords.y]?.element == pixel.element && pixelMap[coords.x][coords.y].temp < pixel.temp) { + swapPixels(pixel,pixelMap[coords.x][coords.y]); + moved = true; break + } else { + if (tryMove(pixel, coords.x, coords.y)) { moved = true; break; } + else { move1Spots.splice(move1Spots.indexOf(coords), 1);} + } + } + if (!moved && !pixel.del) { + var move2Spots = [ + [pixel.x, pixel.y+1], + [pixel.x+1, pixel.y], + [pixel.x-1, pixel.y], + ] + for (var i = 0; i < move2Spots.length; i++) { + var coords = move2Spots[Math.floor(Math.random()*move2Spots.length)]; + if (tryMove(pixel, coords[0], coords[1])) { break; } + else { move2Spots.splice(move2Spots.indexOf(coords), 1); } + } + } + if (!pixel.del) { doDefaults(pixel); } + if (!pixel.del && settings.burn===0 && (pixelTicks-pixel.start > 70) && Math.random() < 0.1 ) { changePixel(pixel,"smoke",false) }; }; //New elements @@ -3948,6 +4085,168 @@ color1 and color2 spread through striped paint like dye does with itself. col stain: 0.075, }; + elements.holy_fire = { + color: ["#FFFF96","#FFBF49","#CE743B"], //placeholder + tick: function(pixel) { + + var moveResult = tryMoveAndReturnBlockingPixel(pixel,pixel.x + randomSign(),pixel.y - 1); + var blockingPixels = []; + var secondMoveResult = null; + + if(typeof(moveResult) == "object" && !(elements[pixel.element].ignore.concat(pixel.element).includes(moveResult.element))) { + blockingPixels.push(moveResult) + }; + + //if move1Result = true then nothing else happens + + if(moveResult !== true) { + var coords = randomChoice([[-1,0],[0,1],[1,0]]).map(offsetPair => addArraysInPairs(offsetPair,[pixel.x,pixel.y])); + secondMoveResult = tryMoveAndReturnBlockingPixel(pixel,...coords); + + if(typeof(secondMoveResult) == "object" && !(elements[pixel.element].ignore.concat(pixel.element).includes(secondMoveResult.element))) { + blockingPixels.push(secondMoveResult) + }; + }; + + if(blockingPixels.length > 0) { + blockingPixels.forEach(function(pixel) { + var blessRxn = elements.bless.reactions[pixel.element]; + if(typeof(blessRxn) == "object") { + var elem2 = blessRxn.elem2; + if(elem2 !== null) { + while(Array.isArray(elem2)) { elem2 = randomChoice(elem2) }; + changePixel(pixel,elem2) + } + }; + var value = Math.random(); + if(value < 0.01) { + if(pixel.burnInto) { + finishBurn(pixel) + } else { + changePixel(pixel,randomChoice(["ash","ash","light"])) + } + } else if(value < 0.20) { + pixel.burning = true; + pixel.burnStart ??= pixelTicks; + } else if(value < 0.205) { + changePixel(pixel,randomChoice(["ash","ash","light"])) + } else { + pixel.temp += 10; pixelTempCheck(pixel) + }; + return + }) + }; + + doDefaults(pixel); + }, + temp:6000, + tempLow:1000, + stateLow: ["bless","fire"], + burnInto: ["bless","fire"], + category: "energy", + burning: true, + burnTime: 500, + burnTempChange: 8, + fireElement: ["bless","plasma"], + ignore: ["ash","light","bless","plasma","wall"], + state: "gas", + density: 0.08, + ignoreAir: true + }; + + elements.bless.ignore ??= []; + elements.bless.ignore.push("holy_fire"); + + elements.plasma_explosion = { + color: ["#c78fff","#ea8fff","#be8fff"], + tick: function(pixel) { + explodeAtPlus(pixel.x,pixel.y,10,"plasma","fire"); + return + }, + temp: 6500, + category: "energy", + state: "gas", + density: 1000, + excludeRandom: true, + noMix: true + }; + + elements.god_slayer_fire = { + color: ["#FFBACE","#FC6DCA","#9954B0"], + tick: function(pixel) { + + var moveResult = tryMoveAndReturnBlockingPixel(pixel,pixel.x + randomSign(),pixel.y - 1); + var blockingPixels = []; + var secondMoveResult = null; + + if(typeof(moveResult) == "object" && !(elements[pixel.element].ignore.concat(pixel.element).includes(moveResult.element))) { + blockingPixels.push(moveResult) + }; + + //if move1Result = true then nothing else happens + + if(moveResult !== true) { + var coords = randomChoice([[-1,0],[0,1],[1,0]]).map(offsetPair => addArraysInPairs(offsetPair,[pixel.x,pixel.y])); + secondMoveResult = tryMoveAndReturnBlockingPixel(pixel,...coords); + + if(typeof(secondMoveResult) == "object" && !(elements[pixel.element].ignore.concat(pixel.element).includes(secondMoveResult.element))) { + blockingPixels.push(secondMoveResult) + }; + }; + + if(blockingPixels.length > 0) { + blockingPixels.forEach(function(pixel) { + var value = Math.random(); + var randomDefaultResult = randomChoice(["ash","slag","plasma"]); + var oldTemp = pixel.temp; + if(value < 0.03) { + if(pixel.stateHigh) { + meltPixel(pixel); + } + } else if(value < 0.06) { + if(pixel.burnInto) { + finishBurn(pixel); + } else { + changePixel(pixel,randomDefaultResult) + } + } else if(value < 0.09) { + if(pixel.breakInto) { + breakPixel(pixel); + } else { + changePixel(pixel,randomDefaultResult) + } + } else if(value < 0.24) { + pixel.burning = true; + pixel.burnStart ??= pixelTicks; + } else if(value < 0.245) { + changePixel(pixel,randomDefaultResult) + } else { + pixel.temp += 25; pixelTempCheck(pixel) + }; + if(pixel) { + pixel.temp = Math.max(oldTemp,pixel.temp) + }; + return + }) + }; + + doDefaults(pixel); + }, + temp:10000, + tempLow:1500, + stateLow: ["plasma_explosion","plasma","plasma","plasma","plasma","plasma","plasma","plasma"], + burnInto: ["plasma_explosion","plasma","plasma","plasma","plasma","plasma","plasma","plasma"], + category: "energy", + ignore: ["ash","slag","wall","plasma","fire","smoke"], + burning: true, + burnTime: 500, + burnTempChange: 10, + fireElement: ["plasma"], + state: "gas", + density: 0.07, + ignoreAir: true + }; + elements.cold_torch = { "color": "#4394d6", "behavior": [ @@ -3977,6 +4276,59 @@ color1 and color2 spread through striped paint like dye does with itself. col "stateHigh": "wood", }; + var GTDR = { "elem1": "torch", chance: 0.01 }; //grand torch degradation reaction + + elements.grand_torch = { + "color": "#FFBF2F", + "tick": function(pixel) { + var coords = circleCoords(pixel.x,pixel.y,2).concat([[-1,-2],[1,-2],[-1,2],[1,2],[-2,-1],[2,-1],[-2,1],[2,1],[-1,-3],[0,-3],[1,-3],[0,-4],[0,-5]].map( + function(offsets) { + return {x: offsets[0]+pixel.x, y: offsets[1]+pixel.y} + } + )); + for(var i = 0; i < coords.length; i++) { + var coordPair = coords[i]; + if(outOfBounds(coordPair.x,coordPair.y)) { continue }; + if(coordPair.x == pixel.x && coordPair.y == pixel.y) { continue }; + if(!(isEmpty(coordPair.x,coordPair.y))) { continue }; + var newPixel = tryCreatePixelReturn("fire",coordPair.x,coordPair.y); + if(typeof(newPixel) == "object") { + newPixel.temp = pixel.temp + } + }; + }, + "reactions": { + "water": GTDR, + "sugar_water": GTDR, + "salt_water": GTDR, + "seltzer": GTDR, + "dirty_water": GTDR, + "pool_water": GTDR, + "steam": GTDR, + "smog": GTDR, + "rain_cloud": GTDR, + "cloud": GTDR, + "snow_cloud": GTDR, + "hail_cloud": GTDR, + "black_damp": { "elem1": "wood", chance: 0.02 }, + "magic": { "elem1": ["grand_torch","grand_torch","grand_plasma_torch"], "elem2": null, changeTemp: true } + }, + "temp": 1500, + "category": "special", + "breakInto": "charcoal", + "tempHigh": 6000, + "stateHigh": "grand_plasma_torch", + "tempLow": 1000, + "stateLow": "torch", + }; + + elements.torch.reactions ??= {}; + elements.torch.reactions.magic = { elem1: ["torch","torch","grand_torch"], elem2: null, changeTemp: true }; + elements.torch.tempHigh = 1500; + elements.torch.stateHigh = "grand_torch"; + + var PTDR = { "elem1": "wood", chance: 0.003 }; + elements.plasma_torch = { "color": "#86579c", "tick": function(pixel) { @@ -4032,25 +4384,68 @@ color1 and color2 spread through striped paint like dye does with itself. col } }, "reactions": { - "water": { "elem1": "wood" }, - "sugar_water": { "elem1": "wood" }, - "salt_water": { "elem1": "wood" }, - "seltzer": { "elem1": "wood" }, - "dirty_water": { "elem1": "wood" }, - "pool_water": { "elem1": "wood" }, - "steam": { "elem1": "wood" }, - "smog": { "elem1": "wood" }, - "rain_cloud": { "elem1": "wood" }, - "cloud": { "elem1": "wood" }, - "snow_cloud": { "elem1": "wood" }, - "hail_cloud": { "elem1": "wood" }, - "black_damp": { "elem1": "wood" } + "water": PTDR, + "sugar_water": PTDR, + "salt_water": PTDR, + "seltzer": PTDR, + "dirty_water": PTDR, + "pool_water": PTDR, + "steam": PTDR, + "smog": PTDR, + "rain_cloud": PTDR, + "cloud": PTDR, + "snow_cloud": PTDR, + "hail_cloud": PTDR, + "black_damp": { "elem1": "wood", change: 0.02 } }, "temp": 7000, "category": "special", "breakInto": "charcoal", "tempLow": 4999, - "stateLow": "torch", + "stateLow": "grand_torch", + }; + + var GrPTDR = { "elem1": "plasma_torch", chance: 0.001 }; //grand plasma torch degradation reaction + + elements.grand_plasma_torch = { + "color": "#b92eff", + "tick": function(pixel) { + var coords = circleCoords(pixel.x,pixel.y,4).concat([[4,4],[4,4],[3,3],[3,3],[1,1],[-1,-1],[-3,-3],[-4,-4],[-4,-4],[-3,-3],[-1,-1],[1,1],[0,0],[0,0],[0,0],[0,0],[1,1],[1,1],[2,2],[-1,-1],[-1,-1],[-2,-2]].map( //ae = filterCurrentPixels(function(pixel) { return pixel.element == "ivory_growth_crystal" }).map(px => [130-px.x,67-px.y]) + function(offsets) { + return {x: offsets[0]+pixel.x, y: offsets[1]+pixel.y} + } + )); + for(var i = 0; i < coords.length; i++) { + var coordPair = coords[i]; + if(outOfBounds(coordPair.x,coordPair.y)) { continue }; + if(coordPair.x == pixel.x && coordPair.y == pixel.y) { continue }; + if(!(isEmpty(coordPair.x,coordPair.y))) { continue }; + var newPixel = tryCreatePixelReturn("plasma",coordPair.x,coordPair.y); + if(typeof(newPixel) == "object") { + newPixel.temp = pixel.temp + } + }; + }, + "reactions": { + "water": GrPTDR, + "sugar_water": GrPTDR, + "salt_water": GrPTDR, + "seltzer": GrPTDR, + "dirty_water": GrPTDR, + "pool_water": GrPTDR, + "steam": GrPTDR, + "smog": GrPTDR, + "rain_cloud": GrPTDR, + "cloud": GrPTDR, + "snow_cloud": GrPTDR, + "hail_cloud": GrPTDR, + "black_damp": { "elem1": "wood", chance: 0.02 }, + }, + "temp": 8500, + "category": "special", + "breakInto": "charcoal", + "tempLow": 6000, + "stateLow": "plasma_torch", }; elements.rad_torch = { @@ -4126,7 +4521,7 @@ color1 and color2 spread through striped paint like dye does with itself. col burn: 300, burnTime: 500, temp: airTemp, - }, + }; elements.hypernapalm = { name: "h y p e r n a p a l m", //HYPERNAPALM @@ -4146,7 +4541,7 @@ color1 and color2 spread through striped paint like dye does with itself. col burnTempChange: 30, burn: 300, burnTime: 500, - }, + }; elements.cold_napalm = { color: "#3e87e0", @@ -4164,7 +4559,7 @@ color1 and color2 spread through striped paint like dye does with itself. col fireElement: "cold_fire", burnTempChange: -1, burnInto: "cold_fire", - } + }; elements.rad_napalm = { color: "#cdf760", @@ -4183,8 +4578,8 @@ color1 and color2 spread through striped paint like dye does with itself. col fireElement: "rad_fire", temp: airTemp, burnInto: "rad_fire", - }, - + }; + runAfterLoad(function() { if(eLists.spout) { eLists.spout.push("cold_torch"); @@ -4505,9 +4900,12 @@ color1 and color2 spread through striped paint like dye does with itself. col })} // shuffle the pixels if not paused*/ for (var i = 0; i < newCurrentPixels.length; i++) { pixel = newCurrentPixels[i]; + if(typeof(elements[pixel.element]) == "undefined") { continue }; + if(typeof(pixel) == "undefined") { continue }; //if (pixelMap[pixel.x][pixel.y] == undefined || currentPixels.indexOf(pixel) == -1) {continue} if (pixel.del) {continue} if (!paused || forceTick) { + if(typeof(elements[pixel.element]) == "undefined") { continue }; doVelocity(pixel); if (elements[pixel.element].tick) { // Run tick function if it exists elements[pixel.element].tick(pixel); @@ -4973,6 +5371,7 @@ color1 and color2 spread through striped paint like dye does with itself. col // Reactions newPixel = pixelMap[nx][ny]; var newInfo = elements[newPixel.element]; + if(typeof(newInfo) == "undefined") { return false }; var returnVal = false; if(newInfo.onTryMoveInto !== undefined) { newInfo.onTryMoveInto(newPixel,pixel); @@ -5907,6 +6306,24 @@ color1 and color2 spread through striped paint like dye does with itself. col conduct: 0.48, }, + elements.stainless_steel = { + color: "#7d8181", + behavior: behaviors.WALL, + reactions: { + "pool_water": { elem1:"rust", chance:0.0009 }, + "salt_water": { elem1:"rust", chance:0.0003 }, + "salt": { elem1:"rust", chance:0.0003 }, + "acid": { elem1:"rust" } + }, + tempHigh: 1455.5, + category: "solids", + density: 7930, + conduct: 0.42, + hardness: 0.85 + }; + + elements.steel.reactions.acid = { elem1:"rust" }; + elements.molten_tungsten = { density: 17600, temp: 3500, @@ -5958,11 +6375,10 @@ color1 and color2 spread through striped paint like dye does with itself. col hidden: true, }, - elements.molten_steel = { - reactions: { - "molten_tungsten": { "elem1":"molten_tungstensteel", "elem2":"molten_tungstensteel" } - } - } + elements.molten_steel ??= {}; + elements.molten_steel.reactions ??= {}; + elements.molten_steel.reactions.molten_tungsten = { "elem1":"molten_tungstensteel", "elem2":"molten_tungstensteel" }; + elements.molten_steel.reactions.molten_chromium = { "elem1":"molten_stainless_steel", "elem2":["molten_chromium","molten_chromium","molten_chromium","molten_chromium","molten_chromium","molten_chromium","molten_chromium","molten_chromium","molten_stainless_steel"] }; elements.unrealistically_flammable_substance_bomb = { name: "unrealistically flammable bomb", @@ -6444,7 +6860,7 @@ color1 and color2 spread through striped paint like dye does with itself. col for (let j = -1; j < 2; j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -6471,7 +6887,7 @@ color1 and color2 spread through striped paint like dye does with itself. col for (let j = -3; j < 4; j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -6499,7 +6915,7 @@ color1 and color2 spread through striped paint like dye does with itself. col for (let j = (-1*squadius); j < (squadius+1); j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -6527,7 +6943,7 @@ color1 and color2 spread through striped paint like dye does with itself. col for (let j = (-1*squadius); j < (squadius+1); j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -6555,7 +6971,7 @@ color1 and color2 spread through striped paint like dye does with itself. col for (let j = (-1*squadius); j < (squadius+1); j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -6583,7 +6999,7 @@ color1 and color2 spread through striped paint like dye does with itself. col for (let j = (-1*squadius); j < (squadius+1); j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -6611,7 +7027,7 @@ color1 and color2 spread through striped paint like dye does with itself. col for (let j = (-1*squadius); j < (squadius+1); j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -6639,7 +7055,7 @@ color1 and color2 spread through striped paint like dye does with itself. col for (let j = (-1*squadius); j < (squadius+1); j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -6667,7 +7083,7 @@ color1 and color2 spread through striped paint like dye does with itself. col for (let j = (-1*squadius); j < (squadius+1); j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -6695,7 +7111,7 @@ color1 and color2 spread through striped paint like dye does with itself. col for (let j = (-1*squadius); j < (squadius+1); j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -6723,7 +7139,7 @@ color1 and color2 spread through striped paint like dye does with itself. col for (let j = (-1*squadius); j < (squadius+1); j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -6753,9 +7169,9 @@ color1 and color2 spread through striped paint like dye does with itself. col if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { if(pixel.uwu < 8) { - pixel.uwu += 1 + pixel.uwu++ } else { - pixel.owo += 1 + pixel.owo++ } } } @@ -7603,7 +8019,7 @@ color1 and color2 spread through striped paint like dye does with itself. col } } } else { - if(!settings.bg || settings.bg == "#fffff0") { + if(!settings.bg || settings.bg == "#fffff0") { //7989 yay soshi! pixel.color = "rgb(255,255,247)" } else { pixel.color = "rgb(255,255,240)" @@ -7690,6 +8106,56 @@ color1 and color2 spread through striped paint like dye does with itself. col hardness: 0.7, } + elements.brimstone_slag = { + color: ["#745B57","#534D4A","#463F53","#51113E","#6D283B","#BC4949","#EA9B4E"], + properties: { + needsOffset: true + }, + colorPattern: [ + "FGGFGFGGF", + "FFGFGFFGG", + "DEEDEEDEE", + "DEDEEEEED", + "BDCBACDCB", + "BCADCDDBB", + "ABBCAABCC" + ], + colorKey: { + "A": "#745B57", + "B": "#534D4A", + "C": "#463F53", + "D": "#51113E", + "E": "#6D283B", + "F": "#BC4949", + "G": "#EA9B4E", + }, + behavior: behaviors.POWDER, + hardness: 0.5, + enableOffsetsOnTextureColors: true, + breakInto: ["slag","sulfur"], + tempHigh: 1780, + state: "solid", + category: "solids", + tick: function(pixel) { + if(pixel.needsOffset) { + var offset = (elements[pixel.element].maxColorOffset ?? 15); + offset = randomIntegerFromZeroToValue(offset) * (Math.random() < 0.5 ? -1 : 1); + pixel.color = convertColorFormats(pixel.color,"json"); + for(var k in pixel.color) { pixel.color[k] += offset }; + pixel.color = convertColorFormats(pixel.color,"rgb"); + delete pixel.needsOffset; + return + } + } + }; + + elements.molten_slag ??= {}; + elements.molten_slag.reactions ??= {}; + + elements.molten_slag.reactions.sulfur = elements.molten_slag.reactions.molten_sulfur = elements.molten_slag.reactions.sulfur_gas = elements.molten_sulfur.reactions.slag = elements.sulfur.reactions.molten_slag = { elem1: "brimstone_slag", elem2: null }; + + elements.slag.tempHigh = 1780; + var temp = "firesea,lektre,concoction,mistake,unstable_mistake,toxic_mistake".split(","); for(var i = 0; i < temp.length; i++) { temp[i].state = "liquid"; @@ -7741,6 +8207,104 @@ color1 and color2 spread through striped paint like dye does with itself. col }, }; + function newLegacyFnmDye(colorName,hexColor) { + if(!(hexColor.startsWith("#"))) { hexColor = "#" + hexColor }; + colorName = colorName.toLowerCase(); + var key = `${colorName}_dye`; + var name = `${colorName.replaceAll("_"," ")} dye`; + var pixelColor = changeLuminance(hexColor,0.73333333333333,"multiply","hex",null,false); + + elements[key] = { + "name": name, + "color": pixelColor, + "state": "solid", + "behavior": [ + "XX|XX|XX", + `CC:${hexColor}|CC:${pixelColor}|CC:${hexColor}`, + `M2 AND CC:${hexColor}|M1 AND CC:${hexColor}|M2 AND CC:${hexColor}` + ], + "density": 100, + "category": "dyes" + }; + eLists.DYE.push(key); + elements.concoction.reactions[key] = { "elem1": "mistake", "elem2": null }; + return elements[key] + }; + + var dyeColors = [ + ["rose", "#FF0067"], + ["orange", "#FF7F00"], + ["pink", "#FF7FFF"], + ["purple", "#C700CF"], + ["burgundy", "#9F005F"], + ["peach", "#ffbf7f"], + ["mint", "#4df0a9"], + ["gray", "#7F7F7F"], + ["lime", "#7FFF00"], + ["black", "#000000"], + ["white", "#FFFFFF"], + ["sky_blue", "#99d1f2"] + ]; + + for(var i = 0; i < dyeColors.length; i++) { + newLegacyFnmDye(dyeColors[i][0],dyeColors[i][1]) + }; + + eLists.LED = ["led_r","led_g","led_b"]; + + function newLED(abbrev,hexColor,baseColorOverrideHex=null) { + if(!(hexColor.startsWith("#"))) { hexColor = "#" + hexColor }; + if(baseColorOverrideHex && !(baseColorOverrideHex.startsWith("#"))) { baseColorOverrideHex = "#" + baseColorOverrideHex }; + abbrev = abbrev.toLowerCase(); + var key = `led_${abbrev}`; + var pixelColor = baseColorOverrideHex ?? changeLuminance(hexColor,0x66/0xff,"multiply","hex",null,false); + + elements[key] = { + behavior: behaviors.WALL, + reactions: { + "light": {"charge1":1}, + "liquid_light": {"charge1":1}, + }, + color: pixelColor, + colorOn: hexColor, + category: "machines", + tempHigh: 1500, + stateHigh: ["molten_glass","molten_glass","molten_glass","molten_gallium"], + conduct: 1, + breakInto: "glass_shard" + }; + + eLists.LED.push(key) + }; + + var ledColors = [ + ["c", "#00FFFF"], //cyan + ["y", "#FFFF00"], //yellow + ["m", "#FF00FF"], //magenta (cursed) + ["p", "#AB00C2"], //purple (cursed) + ["v", "#7700FF"], //violet + ["w", "#FFFFFF"], //white (cursed) + ["gy", "#7F7F7F"], //gray (more cursed) + ["bl", "#000000", "#2b2b2b"], //black (super cursed) + ["o", "#FF7F00"], //orange + ["a", "#FFBF00"], //amber + ["l", "#7FFF00"], //lime + ["rs", "#FF0067"], //rose (cursed) + ["pk", "#FF7FFF"], //pink (cursed) + ["bg", "#9F005F"], //burgundy (cursed) + ["pc", "#ffbf7f"], //peach + ["mg", "#4df0a9"], //mint green + ["sb", "#99d1f2"] //sky blue (cursed) + ]; + + for(var i = 0; i < ledColors.length; i++) { + newLED(...ledColors[i]); + }; + + for(var i = 0; i < eLists.LED.length; i++) { + var key = eLists.LED[i]; + elements.malware.reactions[key] = { elem2:eLists.LED, chance:0.01 } + }; //ASSORTED RAINBOW VARIANTS ## @@ -7986,7 +8550,7 @@ color1 and color2 spread through striped paint like dye does with itself. col var baseJSON = convertColorFormats(baseColor,"json"); var dyeJSON = convertColorFormats(dyeColor,"json"); var dyedColor = multiplyColors(dyeJSON,baseJSON,"json"); - //70% multiplied //7989 yay soshi! + //70% multiplied var semiDyedColor = averageColorObjects(dyedColor,baseJSON,0.7); //35% dye color, 65% result var finalColor = averageColorObjects(semiDyedColor,dyeJSON,0.65); @@ -9802,7 +10366,7 @@ color1 and color2 spread through striped paint like dye does with itself. col for (let j = -1; j < 2; j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == "msmine") { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -10154,7 +10718,7 @@ color1 and color2 spread through striped paint like dye does with itself. col for (let j = -1; j < 2; j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1; + pixel.uwu++; }; }; }; @@ -10246,7 +10810,7 @@ color1 and color2 spread through striped paint like dye does with itself. col for (let j = -1; j < 2; j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1; + pixel.uwu++; }; }; }; @@ -11391,7 +11955,7 @@ color1 and color2 spread through striped paint like dye does with itself. col var elemsAbove = []; var pX = pixel.x; var pY = pixel.y; for(var counter = pY - 1; counter > 0; counter--) { - console.log(pX,pY); + //console.log(pX,pY); if(isEmpty(pX,counter,true)) { break }; @@ -11406,7 +11970,7 @@ color1 and color2 spread through striped paint like dye does with itself. col return } else { pixel.target = elemsAbove - console.log(pixel.target); + //console.log(pixel.target); pixel.charge = 0; } }; @@ -15064,9 +15628,14 @@ Pixel size (rendering only): (Use if the save looks cut o viscosity: 3**4, } - elements.redstone_dust.tempHigh = 2500 + elements.redstone_dust.tempHigh = 2500; - elements.redstone_dust.stateHigh = "destabilized_redstone" + elements.redstone_dust.stateHigh = "destabilized_redstone"; + + elements.redstone_dust.conduct = 0.9; + + elements.redstone_dust.colorOn = ["#FF2424","#FF0000","#FF1200"]; + elements.redstone_dust.color = ["#7f0000","#5f0000","#5f0500"]; elements.destabilized_redstone = { color: ["#9e0303", "#98061a", "#b80704", "#c4020c", "#f70008", "#9e0303", "#98061a", "#b80704", "#e3020a", "#8c0303", "#8c0303"], @@ -16297,9 +16866,10 @@ Pixel size (rendering only): (Use if the save looks cut o "fire": { elem2: null } }, tick: function(pixel) { - backgroundColor = hexToRGB(settings.bg); - pixel.rgbValue = "rgb("+backgroundColor.r+","+backgroundColor.g+","+backgroundColor.b+")"; - pixel.color = pixel.rgbValue; + /*var baseColor = settings.bg instanceof Array ? averageRgbPrefixedColorArray(settings.bg.map(x => convertColorFormats(x,"rgb"))) : convertColorFormats(settings.bg,"rgb"); + baseColor = convertColorFormats(baseColor,"json"); + pixel.color = "rgba(" + Object.values(baseColor).join(",") + ",0)"*/ + pixel.color = "rgba(0,0,0,0)" }, hardness: 0.6, category: "gases", @@ -18822,9 +19392,12 @@ Pixel size (rendering only): (Use if the save looks cut o if(isNaN(pixel.temp)) { pixel.temp = 20 }; if(Math.random() < 0.013 && exposedToAir(pixel)) { changePixel(pixel,"vivite_oxide",false); - pixel.temp += 0.1; + pixel.temp += 4; }; }, + burnTime: 160, + burnTempChange: 10.65, + burnInto: "vivite_oxide_powder", noResistance: true, reactions: { "ice": { elem1: "vivite_oxide", elem2: null, temp1: 0.2 }, @@ -18854,10 +19427,23 @@ Pixel size (rendering only): (Use if the save looks cut o behavior: behaviors.POWDER, tick: function(pixel) { if(Math.random() < 0.027 && exposedToAir(pixel)) { - changePixel(pixel,"vivite_oxide_powder",false); - pixel.temp += 0.1; + if(getEmptyMooreNeighbors(pixel).length > 4) { + pixel.burning = true; + pixel.burnStart = pixelTicks; + } else { + pixel.temp += 18; + changePixel(pixel,getStateAtTemp("vivite_oxide_powder",pixel.temp),false); + }; + + if(pixel.burning && ((pixel.temp + (2 * elements[pixel.element].burnTempChange)) > elements[pixel.element].tempHigh)) { + changePixel(pixel,elements[pixel.element].burnInto,false); + pixel.temp += 213; + }; }; }, + burnTime: 8, + burnTempChange: 213, + burnInto: "vivite_oxide_powder", reactions: { "ice": { elem1: "vivite_oxide_powder", elem2: null, temp1: 0.2 }, "water": { elem1: "vivite_oxide_powder", elem2: null, temp1: 0.2 }, @@ -18872,7 +19458,7 @@ Pixel size (rendering only): (Use if the save looks cut o "salt_ice": { elem1: "vivite_oxide_powder", elem2: "salt" } }, noResistance: true, - tempHigh: 938, + tempHigh: 1725, stateHigh: "molten_vivite", category: "solids", state: "solid", @@ -18909,7 +19495,7 @@ Pixel size (rendering only): (Use if the save looks cut o return false; }; - if(elements[newElement].noViviteSlag) { //Excluded + if(elements[newElement].noViviteSlag || elements[pixel.element].ignore?.includes(newPixel.element)) { //Excluded return false; }; @@ -18926,12 +19512,13 @@ Pixel size (rendering only): (Use if the save looks cut o color: ["#f7a6e5", "#fa70d1", "#f0bbf2"], colorOn: ["#ff63ac", "#ff21bd", "#e81af0"], fireColor: ["#ff66ba", "#ff85ef", "#ff99f7"], + ignore: ["wall","heejinite","jinsoulite","haseulite","molten_heejinite","molten_jinsoulite","molten_haseulite","yvesite","molten_yvesite"], tick: function(pixel) { var info = elements[pixel.element]; if(Math.random() < 0.022 && exposedToAir(pixel)) { changePixel(pixel,pixel.temp > 7315.27 ? "molten_vivite_oxide" : "vivite_oxide_powder",false) - pixel.temp += 0.1; + pixel.temp += 18; }; if(Math.random() < 0.025) { @@ -18975,10 +19562,13 @@ Pixel size (rendering only): (Use if the save looks cut o }, density: 8212, state: "liquid", + burnTime: 160, + burnTempChange: 10.65, + burnInto: "vivite_oxide_powder", hardness: 0.88, viscosity: 10000, breakInto: "vivite_gas", - temp: 1100, + temp: 2000, tempHigh: 2256, stateHigh: "vivite_gas", tempLow: 938, @@ -19109,13 +19699,22 @@ Pixel size (rendering only): (Use if the save looks cut o fireColor: ["#ff66ba", "#ff85ef", "#ff99f7"], tick: function(pixel) { if(Math.random() < 0.032 && exposedToAir(pixel)) { - changePixel(pixel,pixel.temp > 15500 ? "vivite_oxide_gas" : pixel.temp > 7315.27 ? "molten_vivite_oxide" : "vivite_oxide_powder",false); + if(getEmptyMooreNeighbors(pixel).length > 4) { + pixel.burning = true; + pixel.burnStart = pixelTicks; + } else { + pixel.temp += 18; + changePixel(pixel,pixel.temp > 15500 ? "vivite_oxide_gas" : pixel.temp > 7315.27 ? "molten_vivite_oxide" : "vivite_oxide_powder",false); + }; }; }, behavior: behaviors.GAS, state: "gas", tempLow: 2256, stateLow: "molten_vivite", + burnTime: 8, + burnTempChange: 213, + burnInto: "vivite_oxide_powder", density: 18.02, temp: 3300, hardness: 1, @@ -22325,7 +22924,7 @@ Pixel size (rendering only): (Use if the save looks cut o elements.water.reactions[particulateName] = { "elem1": suspensionName, "elem2": [particulateName,particulateName,particulateName,suspensionName], - chance: 0.01 + chance: 0.001 }; //Sediment suspension @@ -25586,7 +26185,7 @@ Pixel size (rendering only): (Use if the save looks cut o }; for(var i in adjacentCoords) { if(Math.random() < 0.005) { - pixel.temp+=1; + pixel.temp++; var newCoords = [ pixel.x+adjacentCoords[i][0], pixel.y+adjacentCoords[i][1] @@ -28761,9 +29360,6 @@ Make sure to save your command in a file if you want to add this preset again.` elements.portal_out = { color: "#2222ee", - properties: { - channel: 0 - }, insulate: true, tick: function(pixel) { pixel._channel = Math.floor(pixel.temp / 100); @@ -28967,15 +29563,16 @@ Make sure to save your command in a file if you want to add this preset again.` if(Array.isArray(breakIntoElement)) { breakIntoElement = breakIntoElement[Math.floor(Math.random() * breakIntoElement.length)] }; - if(typeof(breakIntoElement) === "undefined" || breakIntoElement === null) { + if(breakIntoElement === null) { deletePixel(pixel.x,pixel.y); return true; }; + if(typeof(breakIntoElement) === "undefined") { return false }; changePixel(pixel,breakIntoElement,changetemp) return true; }; - defaultHardness = 0; + defaultHardness = 0.3; function arrowAltTb(pixel,breakChanceMultiplier,changetemp=false,defaultBreakIntoDust=false) { var info = elements[pixel.element]; @@ -34879,7 +35476,7 @@ Make sure to save your command in a file if you want to add this preset again.` }; createPixel(newfire,x,y); //add fire var firePixel = pixelMap[x][y]; - firePixel.temp = Math.max(elements[newfire].temp,firePixel.temp); + firePixel.temp = Math.max(elements[newfire].temp ?? 0,elements.fire.temp,firePixel.temp ?? 0); firePixel.burning = true; }; }; @@ -34891,6 +35488,216 @@ Make sure to save your command in a file if you want to add this preset again.` pixel.temp += (800 * ((1 + (7 * damage)) ** 2) * ((power ** 2) * 1.5)); }; + //explodeAtPlus(x,y,radius,fire="fire",smoke="smoke",beforeFunction=null,afterFunction=null,changeTemp=true) { + //beforeFunction(pixel,x,y,radius,fire,smoke,power,damage) + function wallBombBeforeFunction(pixel,x,y,radius,fire,smoke,power,damage) { + var hardness = (elements[pixel.element].hardness ?? 0) / 2; + damage = damage * ((1 - hardness)*10); + //console.log(damage); + if(damage > 0.25) { + pixel.breakInto ? breakPixel(pixel) : deletePixel(pixel.x,pixel.y) + }; + return + }; + + elements.wall_bomb = { + color: "#af8f8f", + tick: function(pixel) { + doDefaults(pixel); + if(!isEmpty(pixel.x,pixel.y-1,true)) { //[0][1] EX (ignore bounds) + var newPixel = pixelMap[pixel.x][pixel.y-1]; + var newElement = newPixel.element; + var newInfo = elements[newElement]; + if(newInfo.state !== "gas" && newElement !== pixel.element) { + explodeAtPlus(pixel.x,pixel.y,10,"fire","smoke",wallBombBeforeFunction,null,false); + if(pixel) { deletePixel(pixel.x,pixel.y) }; + return + }; + }; + if(!isEmpty(pixel.x,pixel.y+1,true)) { //[2][1] EX (don't ignore bounds, non-bound case) + var newPixel = pixelMap[pixel.x][pixel.y+1]; + var newElement = newPixel.element; + var newInfo = elements[newElement]; + if(newInfo.state !== "gas" && newElement !== pixel.element) { + explodeAtPlus(pixel.x,pixel.y,10,"fire","smoke",wallBombBeforeFunction,null,false); + if(pixel) { deletePixel(pixel.x,pixel.y) }; + return + }; + }; + if(outOfBounds(pixel.x,pixel.y+1)) { //[2][1] EX (don't ignore bounds, bound case) + explodeAtPlus(pixel.x,pixel.y,10,"fire","smoke",wallBombBeforeFunction,null,false); + if(pixel) { deletePixel(pixel.x,pixel.y) }; + return + }; + if(!tryMove(pixel,pixel.x,pixel.y+1)) { //behaviors.POWDER + Math.random() < 0.5 ? tryMove(pixel,pixel.x-1,pixel.y+1) : tryMove(pixel,pixel.x+1,pixel.y+1); + }; + }, + category: "weapons", + state: "solid", + density: 3000, + excludeRandom: true, + }; + + elements.tsunami = { + color: ["#2449d1","#4b6adb","#8093d9"], + behavior: behaviors.WALL, + properties: { + active: true, + }, + tick: function(pixel) { + //Iteration initial checks + if(!pixel) { + return; + }; + if(!pixel.active) { + deletePixel(pixel.x,pixel.y); + }; + + //Initial property-setting + var pixelIsOnLeft = (pixel.x < (width/2)); + pixel.fromX ??= pixelIsOnLeft ? 1 : width - 1; + pixel.direction ??= pixelIsOnLeft ? 1 : -1; + + var floorHeight = pixel.y + 1; + while(isEmpty(pixel.x,floorHeight,false)) { + floorHeight++ + }; + pixel.floorHeight ??= floorHeight; + + //Actual doer code + var newX = pixel.fromX + pixel.direction; + + if(outOfBounds(newX,1)) { + pixel.active = false; + return + }; + + var bottomY = (pixel.floorHeight + 3); //extend 4 pixels below + var topY = bottomY - 13; //topY < bottomY because in this game +Y is *downward* + for(var i = bottomY; i >= topY; i--) { + var waterToDo = randomChoice(["salt_water","dirty_water"]); + var fc = {x: newX, y: i}; + if(outOfBounds(fc.x,fc.y)) {continue}; + if(isEmpty(fc.x,fc.y,false)) { + //fill with water + createPixel(waterToDo,fc.x,fc.y) + } else { + var newPixel = pixelMap[fc.x]?.[fc.y]; + if(!newPixel) { continue }; + //break + tryBreak(newPixel,true,true); + if(!newPixel) { continue }; + //water reaction steal + if(elements[newPixel.element].reactions?.water) { + var waterRxn = elements[newPixel.element].reactions.water; + var elem2 = waterRxn.elem2; + while(Array.isArray(elem2)) { + elem2 = randomChoice(elem2) + }; + if(elem2 !== null) { + changePixel(newPixel,elem2,true) + } + }; + if(!newPixel) { continue }; + //add velocity; + newPixel.vx ??= 0; + newPixel.vy ??= 0; + newPixel.vx += (pixel.direction * 6) + newPixel.vy += 3; + }; + }; + pixel.fromX += pixel.direction + }, + state: "solid", + category: "special", + density: elements.water.density + }; + + elements.lava_tsunami = { + color: ["#ff370a","#e84a23","#e67740"], + behavior: behaviors.WALL, + properties: { + active: true, + }, + tick: function(pixel) { + //Iteration initial checks + if(!pixel) { + return; + }; + if(!pixel.active) { + deletePixel(pixel.x,pixel.y); + }; + + //Initial property-setting + var pixelIsOnLeft = (pixel.x < (width/2)); + pixel.fromX ??= pixelIsOnLeft ? 1 : width - 1; + pixel.direction ??= pixelIsOnLeft ? 1 : -1; + + var floorHeight = pixel.y + 1; + while(isEmpty(pixel.x,floorHeight,false)) { + floorHeight++ + }; + pixel.floorHeight ??= floorHeight; + + //Actual doer code + var newX = pixel.fromX + pixel.direction; + + if(outOfBounds(newX,1)) { + pixel.active = false; + return + }; + + var bottomY = (pixel.floorHeight + 3); //extend 4 pixels below + var topY = bottomY - 13; //topY < bottomY because in this game +Y is *downward* + for(var i = bottomY; i >= topY; i--) { + var fc = {x: newX, y: i}; + if(outOfBounds(fc.x,fc.y)) {continue}; + if(isEmpty(fc.x,fc.y,false)) { + //fill with lava + createPixelReturn("magma",fc.x,fc.y).temp = 1400; + } else { + var newPixel = pixelMap[fc.x]?.[fc.y]; + if(!newPixel) { continue }; + var data = elements[newPixel.element]; + //break + for(var j = 0; j < 3; j++) { + tryBreak(newPixel,true,j == 0); + if(!newPixel) { break } + }; + //water reaction steal + if(data.reactions?.magma) { + var magmaRxn = data.reactions.magma; + var elem2 = magmaRxn.elem2; + while(Array.isArray(elem2)) { + elem2 = randomChoice(elem2) + }; + if(elem2 !== null) { + changePixel(newPixel,elem2,true) + } + }; + if(!newPixel) { continue }; + newPixel.temp = Math.max(newPixel.temp,1400); pixelTempCheck(newPixel); + if(!newPixel) { continue }; + if(newPixel.element == "fire") { changePixelReturn(newPixel,"magma",true).temp = 1400 }; + if(data.burn) { newPixel.burning = true; newPixel.burnStart = pixelTicks }; + if(Math.random() < 0.1 && newPixel.burnInto) { finishBurn(newPixel) }; + if(newPixel.element == "fire") { changePixelReturn(newPixel,"magma",true).temp = 1400 }; + if(!newPixel) { continue }; + //add velocity; + newPixel.vx ??= 0; + newPixel.vy ??= 0; + newPixel.vx += (pixel.direction * 6) + newPixel.vy += 3; + }; + }; + pixel.fromX += pixel.direction + }, + state: "solid", + category: "special", + density: elements.magma.density + }; + function empCharge(pixel,x,y,radius,fire,smoke,power,damage) { var info = elements[pixel.element]; if(info.conduct) { @@ -35713,6 +36520,8 @@ Make sure to save your command in a file if you want to add this preset again.` excludeRandom: true, hardness: 0.3, }; + + //Wall bomb elements.electric_cluster_bomb = { color: "#ffffff", @@ -38541,7 +39350,7 @@ Make sure to save your command in a file if you want to add this preset again.` case "bomb": var number = prompt(`Enter a bomb number (default: 1) 1 corresponds to radius 10, 2 corresponds to radius 15, etc.`); - isNaN(parseFloat(number)) ? number = 0 : number = parseFloat(number); + isNaN(parseFloat(number)) ? number = 1 : number = parseFloat(number); amount += generateBomb(elements,true,number).length; break; default: @@ -40239,7 +41048,7 @@ Make sure to save your command in a file if you want to add this preset again.` for (var i = 1; i < width; i++) { for (var j = 1; j < height; j++) { if (!isEmpty(i,j)) { - pixelMap[i][j].temp += 1 + pixelMap[i][j].temp++ } } } @@ -40318,7 +41127,7 @@ Make sure to save your command in a file if you want to add this preset again.` for (let j = -8; j < 9; j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -40355,7 +41164,7 @@ Make sure to save your command in a file if you want to add this preset again.` for (let j = -8; j < 9; j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -40391,7 +41200,7 @@ Make sure to save your command in a file if you want to add this preset again.` for (let j = -8; j < 9; j++) { if (!isEmpty(pixel.x+j,pixel.y+i) && !outOfBounds(pixel.x+j,pixel.y+i)) { if (pixelMap[pixel.x+j][pixel.y+i].element == pixel.element) { - pixel.uwu += 1 + pixel.uwu++ } } } @@ -44085,7 +44894,36 @@ maxPixels (default 1000): Maximum amount of pixels/changes (if xSpacing and ySpa //console.log(currentElement); }); - //END ## + //MISCELLANEOUS CHANGES ## + + eLists.PIPE = ['pipe', 'destroyable_pipe', 'e_pipe', 'destroyable_e_pipe', 'channel_pipe', 'destroyable_channel_pipe', 'bridge_pipe']; + + elements.pipe_stage_shifter = { + tool: function(pixel) { + if(!(eLists.PIPE.includes(pixel.element))) { return false }; + if(typeof(pixel.stage) == "undefined" || !(pixel.stage) || pixel.stage < 2) { return false }; + switch (pixel.stage) { + case 2: pixel.stage = 3; break; + case 3: pixel.stage = 4; break; + case 4: pixel.stage = 2; break; + default: pixel.stage = (((Math.max(2,Math.floor(pixel.stage)) - 2) % 3) + 2); + }; + switch (pixel.stage) { + case 2: newColor = "#003600"; break; + case 3: newColor = "#360000"; break; + case 4: newColor = "#000036"; break; + }; + pixel.color = pixelColorPick(pixel,newColor); + }, + category: "tools", + color: ["#003600","#360000","#000036"], + density: elements.steel.density, + hardness: elements.steel.hardness, + tempHigh: elements.steel.tempHigh, + stateHigh: "molten_steel", + state: "solid", + behavior: behaviors.POWDER + }; var notActuallyMovable = ["pipe","e_pipe","steel","vivite"]; @@ -44102,6 +44940,8 @@ maxPixels (default 1000): Maximum amount of pixels/changes (if xSpacing and ySpa behavior: behaviors.WALL, maxColorOffset: 0 }; + + //END ## } catch (error) { alert(`Load failed (try reloading)\nError: ${error.stack}`); console.error(error) diff --git a/mods/logicgates.js b/mods/logicgates.js index c3002c58..5b989a41 100644 --- a/mods/logicgates.js +++ b/mods/logicgates.js @@ -197,6 +197,48 @@ elements.or_gate = { } } } +elements.nand_gate = { + color: "#eb4034", + category: "logic", + state: "solid", + behavior: behaviors.WALL, + tick: function(pixel){ + var countNeighborsResult = countNeighbors() + if (countNeighborsResult.uncharged){ + chargeOutputs(); + } else { + unchargeOutputs(); + } + } +} +elements.nor_gate = { + color: "#eb8c34", + category: "logic", + state: "solid", + behavior: behaviors.WALL, + tick: function(pixel){ + var countNeighborsResult = countNeighbors() + if (!countNeighborsResult.charged){ + chargeOutputs(); + } else { + unchargeOutputs(); + } + } +} +elements.nxor_gate = { + color: "#ebd834", + category: "logic", + state: "solid", + behavior: behaviors.WALL, + tick: function(pixel){ + var countNeighborsResult = countNeighbors() + if (!(countNeighborsResult.charged == 1)){ + chargeOutputs(); + } else { + unchargeOutputs(); + } + } +} elements.E2L_lever = { color: "#b2ba75", behavior: behaviors.WALL, @@ -347,6 +389,7 @@ elements.logic_transmitter = { if (pixel.start === pixelTicks){ pixel.channel = transmitterVar; } + pixel.clone = pixel.channel; var receivers = currentPixels.filter(function(pixelToCheck) { return ( pixelToCheck !== pixel && //should work if this pixel is the same as the other one by reference @@ -388,5 +431,22 @@ elements.logic_receiver = { category: "logic", tick: function(pixel){ if (pixel.start === pixelTicks){pixel.channel = transmitterVar} + pixel.clone = pixel.channel; } +} +elements.logic_shock = { + color: elements.shock.color, + category: "tools", + tool: function(pixel){ + if (pixel.element == "logic_wire"){pixel.lstate = 2; pixel.color = pixelColorPick(pixel, "#ffe49c")} + }, + excludeRandom: true, +} +elements.logic_unshock = { + color: elements.uncharge.color, + category: "tools", + tool: function(pixel){ + if (pixel.element == "logic_wire"){pixel.lstate = -2; pixel.color = pixelColorPick(pixel, "#3d4d2c")} + }, + excludeRandom: true, } \ No newline at end of file diff --git a/mods/sbstuff.js b/mods/sbstuff.js index cb05c5bd..596e6999 100644 --- a/mods/sbstuff.js +++ b/mods/sbstuff.js @@ -66,7 +66,7 @@ elements.maple_syrup = { tempHigh: 500, stateHigh: "steam", color: "#9c6000", - behavior: behaviors.LIQUID, + behavior: behaviors.CRAWLER, category: "liquids", state: "liquid", }; @@ -362,6 +362,15 @@ elements.coca_cola = { state: "liquid", }; +elements.pepsi = { + tempHigh: 500, + stateHigh: "steam", + color: "#2b1717", + behavior: behaviors.LIQUID, + category: "liquids", + state: "liquid", +}; + elements.piss = { tempHigh: 500, stateHigh: "steam", @@ -1409,7 +1418,7 @@ elements.silver_coin = { state: "solid", }; -elements.max_graphics_in_roblox = { +elements.uraniumaniumaniumaniumanium_popcornicecream_plutoniumeptunium_238239 = { color: "#238fe8", behavior: [ "XX|XX|XX", @@ -1425,7 +1434,199 @@ elements.max_graphics_in_roblox = { excludeRandom: true, maxSize: 1, noMix: true, - desc: "ok now ACTUALLY use it at your own risk IM NOT KIDDING! THIS CAN FUCKING CRASH YOUR GAME" + desc: "ok now ACTUALLY use it at your own risk IM NOT KIDDING! THIS CAN FUCKING CRASH YOUR GAME", + excludeRandom: true, +}; + +elements.coffee_milk = { + tempHigh: 300, + stateHigh: "steam", + color: "#5c4c42", + behavior: behaviors.LIQUID, + category: "liquids", + state: "liquid", +}; + +elements.mentos = { + tempHigh: 500, + stateHigh: "ash", + color: "#d0cbd6", + behavior: behaviors.STURDYPOWDER, + category: "food", + state: "liquid" +}; + +elements.oreo = { + tempHigh: 300, + stateHigh: "steam", + color: ["#211e1e","#fff6f5"], + singleColor: true, + behavior: behaviors.STURDYPOWDER, + category: "food", + state: "liquid" +}; + +elements.uranium_238 = { + tempHigh: 1200, + stateHigh: "molten_uranium", + color: ["#0f400b", "#30522d", "#4d6b4a", "#6f8f6d"], + behavior: [ + "XX|CR:radiation%1|XX", + "CR:radiation%1|CH:lead%0.001|CR:radiation%1", + "M2|M1|M2", + ], + category: "powders", + state: "liquid", + density: 19100, + hardness: 0.6, + conduct: 0.235, + excludeRandom: true, + reactions: { + "neutron": {elem1: "uranium_239",}, + } +}; + +elements.uranium_239 = { + tempHigh: 1300, + stateHigh: "molten_uranium", + color: ["#153816", "#135e14", "#379138", "#567556", "#7bb37b"], + behavior: [ + "XX|CR:radiation%2|XX", + "CR:radiation%2|CH:lead%0.002|CR:radiation%2", + "M2|M1|M2", + ], + category: "powders", + state: "liquid", + hidden: true, + density: 19100, + hardness: 0.6, + conduct: 0.235, + excludeRandom: true, + reactions: { + "electron": {elem1: "neptunium_239"} + } +}; + +elements.neptunium_239 = { + tempHigh: 1500, + stateHigh: "molten_uranium", + color: ["#082e19", "#173b27", "#354a3f", "#4c635a", "#344a41"], + behavior: [ + "XX|CR:radiation%3|XX", + "CR:radiation%3|CH:lead%0.003|CR:radiation%3", + "M2|M1|M2", + ], + category: "powders", + state: "liquid", + hidden: true, + density: 20000, + hardness: 0.7, + conduct: 0.3, + excludeRandom: true, + reactions: { + "electron": {elem1: "plutonium"}, + "neutron": { elem1:"n_explosion", tempMin:500, chance:0.1 } + } +}; + +elements.plutonium = { + tempHigh: 2000, + stateHigh: "molten_uranium", + color: ["#0a4a17", "#194d23", "#263b2a", "#475449"], + behavior: [ + "XX|CR:radiation%4|XX", + "CR:radiation%4|CH:lead%0.004|CR:radiation%4", + "M2|M1|M2", + ], + category: "powders", + state: "liquid", + hidden: true, + density: 22000, + hardness: 0.8, + conduct: 0.4, + excludeRandom: true, + reactions: { + "neutron": { elem1:"n_explosion", tempMin:500, chance:0.2 }, + "electron": { elem1:"n_explosion", tempMin:500, chance:0.00000000000000000000001 } + } +}; + +elements.electron = { + color: "#c99d16", + behavior: behaviors.BOUNCY, + reactions: { + "uranium": { temp2:100 }, + }, + temp: 35, + category: "energy", + state: "gas", + density: 0.00002, + ignoreAir: true +}; + +elements.sned = { + color: "#dfe0d9", + behavior: [ + "XX|XX AND CR:sned%1|XX", + "M2 AND CR:sned%1|XX|M2 AND CR:sned%1", + "M1|M1 AND CH:sned%1|M1", + ], + category: "joke", + state: "liquid", + excludeRandom: true +}; + +elements.uranium_tea = { + temp: 60, + tempHigh: 400, + stateHigh: "molten_uranium", + color: ["#0f8b15", "#316624", "#59864b", "#502e0f"], + behavior: behaviors.RADLIQUID, + category: "liquids", + state: "liquid" +}; + +elements.powerlaser = { + color: ["#ed0ca9","#ff2b95"], + tick: function(pixel) { + var x = pixel.x; + for (var y = pixel.y; y < height; y++) { + if (outOfBounds(x, y)) { + break; + } + if (isEmpty(x, y)) { + if (Math.random() > 0.05) { continue } + createPixel("flash", x, y); + pixelMap[x][y].color = "#b80ced"; + pixelMap[x][y].temp = 1001000; + } + else { + if (elements[pixelMap[x][y].element].isGas) { continue } + if (elements[pixelMap[x][y].element].id === elements.heat_ray.id) { break } + pixelMap[x][y].temp += 901000; + pixelTempCheck(pixelMap[x][y]); + break; + } + } + deletePixel(pixel.x, pixel.y); + }, + temp: 1000000, + category: "energy", + state: "gas", + excludeRandom: true, + noMix: true +}; + +elements.magma_bomb = { + temp: 100, + color: "#b83109", + behavior: [ + "XX|EX:6>magma|XX", + "XX|XX|XX", + "M2|M1 AND EX:6>magma|M2" + ], + category: "weapons", + state: "liquid" }; elements.incinerate.category = "tools", @@ -1463,13 +1664,17 @@ if (!elements.water.reactions) elements.water.reactions = {}; elements.water.reactions.cocaine = { elem1: "solid_water", elem2: null } if (!elements.paper.reactions) elements.paper.reactions = {}; -elements.paper.reactions.bless = { elem1: "robux", elem2: null, chance: 0.001 } +elements.paper.reactions.bless = { elem1: "robux", elem2: null, chance: 0.0000001 } if (!elements.uranium.reactions) elements.uranium.reactions = {}; elements.uranium.reactions.ice_cream = {elem1: "uranium_ice_cream", elem2: null}, -elements.uranium.reactions.cream = {elem1: "uranium_ice_cream", elem2: null} +elements.uranium.reactions.cream = {elem1: "uranium_ice_cream", elem2: null}, +elements.uranium.reactions.tea = {elem1: "uranium_tea", elem2: null} if (!elements.dough.reactions) elements.dough.reactions = {}; elements.dough.reactions.yolk = {elem1: null, elem2: "spaghetti", tempMin: 25} +if (!elements.coffee.reactions) elements.coffee.reactions = {}; +elements.coffee.reactions.milk = {elem1: null, elem2: "coffee_milk",} + elements.silver.breakInto = "silver_coin" diff --git a/mods/weapons.js b/mods/weapons.js index dfb8ed94..04ed8a20 100644 --- a/mods/weapons.js +++ b/mods/weapons.js @@ -25,7 +25,7 @@ elements.little_boy = { cooldown: defaultCooldown }, elements.fat_man = { - color: ["#ffff00","#000000"], + color: ["#ffff00","#333333"], behavior: [ "XX|EX:28>plasma|XX", "XX|XX|XX", @@ -69,20 +69,31 @@ elements.fat_man = { category: "weapons" }, elements.left_missile = { - color: "#4c4e42", + color: "#4c4e42", behavior: [ - "XX|EX:10|XX", - "CR:left_missile AND EX:10|CH:fire|EX:10", - "M2|M1 AND EX:10|M2", + "M2|EX:10|XX", + "M1 AND EX:10|XX|EX:10", + "M2|EX:10|XX", ], category:"weapons", }, elements.right_missile = { - color: "#4c4e42", + color: "#4c4e42", behavior: [ - "XX|EX:10|XX", - "EX:10|CH:fire|EX:10 AND CR:right_missile", - "M2|M1 AND EX:10|M2", + "XX|EX:10|M2", + "EX:10|XX|M1 AND EX:10", + "XX|EX:10|M2", ], category:"weapons", +}, + elements.cluster_munition = { + color: "#444444", + behavior: [ + "XX|EX:10>smoke,smoke,smoke,smoke,bomb,bomb|XX", + "XX|XX|XX", + "M2|M1 AND EX:10>smoke,smoke,smoke,smoke,bomb,cluster_munition|M2", + ], + category: "weapons", + state: "solid", + density: 1300, }; \ No newline at end of file