diff --git a/mods/chem.js b/mods/chem.js index 3b30bea6..2710bcfb 100644 --- a/mods/chem.js +++ b/mods/chem.js @@ -259,7 +259,7 @@ elements.FOOF = { } } } - if (change && Math.random() < 0.5) { + if (change && Math.random() < 0.01) { changePixel(pixel,"explosion"); } else if (Math.random() < 0.0001) { if(Math.random() < 0.5) { @@ -297,7 +297,7 @@ elements.solid_FOOF = { } } } - if (change && Math.random() < 0.5) { + if (change && Math.random() < 0.01) { changePixel(pixel,"explosion"); } else if (Math.random() < 0.00005) { if(Math.random() < 0.5) { @@ -1099,7 +1099,7 @@ elements.ethane = { behavior: behaviors.GAS, reactions: { "steam": { "elem1":"hydrogen", "elem2":"ethylene", "chance":0.01 }, - "chlorine": { "elem1":"chloroethane", "elem2": null } + "chlorine": { "elem1":"chloroethane", "elem2": null, "chance":0.01 } }, category: "gases", tempHigh: 400, @@ -1148,6 +1148,7 @@ elements.ethylene = { behavior: behaviors.GAS, reactions: { "titanium_trichloride": { "elem1":"polyethylene", "elem2":"titanium_trichloride", "chance":0.1 }, + "acid_gas": { "elem1":"chloroethane", "elem2":null }, "diethylaluminium_chloride": { "elem1":"polyethylene", "elem2":"diethylaluminium_chloride", "chance":0.1 }, }, category: "gases", @@ -1161,6 +1162,9 @@ elements.ethylene = { density: 1.356, }; +elements.acid.ignore.push("ethylene","liquid_ethylene","chloroethane","liquid_chloroethane"); +elements.acid_gas.ignore.push("ethylene","liquid_ethylene","chloroethane","liquid_chloroethane"); + elements.titanium = { diff --git a/mods/world_gen_test.js b/mods/world_gen_test.js new file mode 100644 index 00000000..fbcead11 --- /dev/null +++ b/mods/world_gen_test.js @@ -0,0 +1,222 @@ +//https://www.michaelbromley.co.uk/blog/simple-1d-noise-in-javascript/ + +var Simple1DNoise = function() { + var MAX_VERTICES = 256; + var MAX_VERTICES_MASK = MAX_VERTICES -1; + var amplitude = 1; + var scale = 1; + + var r = []; + + for ( var i = 0; i < MAX_VERTICES; ++i ) { + r.push(Math.random()); + } + + var getVal = function( x ){ + var scaledX = x * scale; + var xFloor = Math.floor(scaledX); + var t = scaledX - xFloor; + var tRemapSmoothstep = t * t * ( 3 - 2 * t ); + + /// Modulo using % + var xMin = xFloor % MAX_VERTICES_MASK; + var xMax = ( xMin + 1 ) % MAX_VERTICES_MASK; + + var y = lerp( r[ xMin ], r[ xMax ], tRemapSmoothstep ); + + return y * amplitude; + }; + + /** + * Linear interpolation function. + * @param a The lower integer value + * @param b The upper integer value + * @param t The value between the two + * @returns {number} + */ + var lerp = function(a, b, t ) { + return a * ( 1 - t ) + b * t; + }; + + // return the API + return { + getVal: getVal, + setAmplitude: function(newAmplitude) { + amplitude = newAmplitude; + }, + setScale: function(newScale) { + scale = newScale; + } + }; +}; + +function newHeightMap(pixelType, pixelType2, offset, amplitude1, amplitude2, scale1, scale2) { + return { + color: "#000000", + behavior: behaviors.WALL, + category: "special", + hidden: true, + state: "solid", + offset: 0.5, + pixelType: pixelType, + pixelType2: pixelType2, + offset: offset, + amplitude1: amplitude1, + amplitude2: amplitude2, + scale1: scale1, + scale2: scale2, + generator: new Simple1DNoise(), + generator2: new Simple1DNoise(), + tick: function(pixel) { + generator = this.generator; + generator2 = this.generator2; + generator.setAmplitude(this.amplitude1); + generator.setScale(this.scale1); + generator2.setAmplitude(this.amplitude2); + generator2.setScale(this.scale2); + let value = generator.getVal(pixel.x/width) + generator2.getVal(pixel.x/width); + if(value + this.offset < pixel.y/height) { + let element = this.pixelType; + if(Array.isArray(element)) + { + element = element[Math.floor(Math.random() * element.length)]; + } + if(element == null) + { + deletePixel(pixel.x,pixel.y); + } else { + changePixel(pixel,element); + } + } else { + let element = this.pixelType2; + if(Array.isArray(element)) + { + element = element[Math.floor(Math.random() * element.length)]; + } + if(element == null) + { + deletePixel(pixel.x,pixel.y); + } else { + changePixel(pixel,element); + } + } + } + }; +} + +elements.dunes_height_map = newHeightMap("sand", null, 0, 0.75, 0.05, 2.5, 20); +elements.oasis_height_map = newHeightMap("sand", "water_height", 0.25, 0.75, 0.05, 2.5, 20); +elements.water_height = newHeightMap("water", null, 0.5, 0, 0, 1, 1); +worldgentypes.dunes = { + fill: [ + [0, "dunes_height_map"] + ] + }; +worldgentypes.oasis = { + fill: [ + [0, "oasis_height_map"] + ] + }; + +if (enabledMods.includes("mods/chem.js")) { + elements.ptfe_height_map = newHeightMap("polytetrafluoroethylene", "foof_height", 0.25, 0.75, 0.05, 2.5, 20); + elements.foof_height = newHeightMap("FOOF", Array(100).fill(null).concat(["oxygen","fluorine"]), 0.5, 0, 0, 1, 1); + worldgentypes.FOOF_sea = { + fill: [ + [0, "ptfe_height_map"] + ], + temperature: -120 + }; + elements.francium_height_map = newHeightMap("tungsten", "francium_height", 0.125, 1, 0.2, 2.5, 20); + elements.francium_height = newHeightMap("molten_francium", Array(100).fill(null).concat(["radon","radiation","radiation","radiation"]), 0.5, 0, 0, 1, 1); + worldgentypes.francium_lake = { + fill: [ + [0, "francium_height_map"] + ], + temperature: 30 + }; +} + + +//override function until fix +worldGen = function (worldtype) { + if(worldtype.fill) { + for (var x = 1; x < width; x++) { + for (var y = 0; y < height; y++) { + var element = null; + for (let i = 0; i < worldtype.fill.length; i++) { + if((height-y)/height > worldtype.fill[i][0]) { + element = worldtype.fill[i][1] + } else { + break; + } + } + if (element) { + createPixel(element,x,y); + if (worldtype.temperature) { + pixelMap[x][y].temp = worldtype.temperature; + } + } + } + } + } else { + var complexity = worldtype.complexity || 20; + var heightVariance = worldtype.heightVariance || 0.5; + var baseHeight = height-(height*(worldtype.baseHeight || 0.5)); + var layers = worldtype.layers || {0:"rock"}; + var yoffsets = generateTerrainHeights(width,heightVariance,complexity); + // 2D world vertical generator + for (var x = 1; x < width; x++) { + var yoffset = yoffsets[x]; + var worldHeight = baseHeight+yoffset; + for (var y = 0; y < height; y++) { + // Change element type based on y, from grass > dirt > rock > basalt + if (y > worldHeight) { + // distance from the bottom of worldHeight + var frombottom = worldHeight-(y-worldHeight); + var element = null; + for (var i in layers) { + var layer = layers[i]; + if (layer[0] == 0 && yoffset < 0) { + layer[0] = yoffset; + } + if (frombottom > worldHeight*layer[0] && Math.random() < (layer[2] || 1)) { + if (elements[layer[1]]) { + element = layer[1]; + break + } + } + } + if (element) { + createPixel(element,x,y); + if (worldtype.temperature) { + pixelMap[x][y].temp = worldtype.temperature; + } + } + } + } + } + // decor + if (worldtype.decor) { + for (var i = 0; i < worldtype.decor.length; i++) { + var decor = worldtype.decor[i]; + var element = decor[0]; + var chance = decor[1]; + for (var x = 1; x < width; x++) { + var y = decor[2] || 5; + // add or subtract worldtype.decorVariance from y + y += Math.round(Math.random()*(worldtype.decorVariance||2) - (worldtype.decorVariance||2)/2); + if (Math.random() < chance && isEmpty(x,y)) { + createPixel(element,x,y); + if (worldtype.temperature) { + pixelMap[x][y].temp = worldtype.temperature; + } + if (decor[3]) { + pixelMap[x][y].color = pixelColorPick(pixelMap[x][y],decor[3]) + } + } + } + } + } + } +} \ No newline at end of file