From 515af4a28b9691a945db3b597df26c8d1ce71a8c Mon Sep 17 00:00:00 2001 From: O-01-67 <68935009+O-01-67@users.noreply.github.com> Date: Sun, 9 Oct 2022 13:20:18 -0400 Subject: [PATCH] baby creepers --- mods/mobs.js | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 281 insertions(+), 1 deletion(-) diff --git a/mods/mobs.js b/mods/mobs.js index 79bda649..a9f09685 100644 --- a/mods/mobs.js +++ b/mods/mobs.js @@ -252,7 +252,7 @@ if(enabledMods.includes(runAfterAutogenMod)) { enemyHumanoidArray = ["head","body"] //just in case - spawnCreepers = ["creeper","angelic_creeper","bombing_creeper","hell_creeper"]; + spawnCreepers = ["creeper","baby_creeper","angelic_creeper","bombing_creeper","hell_creeper"]; if(settings.creeperSpawning) { //creeper spawning option randomEvents.creeper = function() { @@ -1684,6 +1684,286 @@ if(enabledMods.includes(runAfterAutogenMod)) { ################## */ + //Baby Creeper + + elements.baby_creeper = { + color: ["#D2D2D2", "#BFDFB9", "#94CE89", "#78D965", "#5ED54C", "#58C546", "#50B143", "#479143", "#559552", "#3F8738", "#5B8B59"], + category: "life", + density: 1500, + state: "solid", + conduct: 25, + tempHigh: 250, + stateHigh: "cooked_meat", + tempLow: -30, + stateLow: "frozen_meat", + burn: 10, + burnTime: 250, + burnInto: ["cooked_meat","cooked_meat","cooked_meat","cooked_meat","gunpowder"], + breakInto: ["blood","gunpowder"], + reactions: { + "cancer": { "elem1":"cancer", "chance":0.005 }, + "radiation": { "elem1":["ash","meat","rotten_meat","cooked_meat"], "chance":0.4 }, + "plague": { "elem1":"plague", "chance":0.05 }, + }, + properties: { + dead: false, + dir: 1, + panic: 0, + charged: false, + didChargeBlueTinted: false, + }, + tick: function(pixel) { + tryMove(pixel, pixel.x, pixel.y+1); // Fall + doHeat(pixel); + doBurning(pixel); + doElectricity(pixel); + if (pixel.dead) { + // Turn into rotten_meat if pixelTicks-dead > 500 + if (pixelTicks-pixel.dead > 200) { + Math.random() < 0.1 ? changePixel(pixel,"gunpowder") : changePixel(pixel,"rotten_meat"); + } + return + } + + if (Math.random() < 0.15) { // Move 15% chance (should be 12.5 but 15 looks better) + var movesToTry = [ + [1*pixel.dir,0], //dash move + [1*pixel.dir,-1], //slash move + ]; + // 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]-1)) { + if(tryMove(pixel, pixel.x+move[0], pixel.y+move[1])) { + break; + }; + }; + }; + // 15% chance to change direction while not chasing a human + if(!pixel.following) { + if (Math.random() < 0.15) { + pixel.dir *= -1; + //console.log("*turns around cutely to face ${pixel.dir < 0 ? 'left' : 'right'}*"); + }; + }/* else { + //console.log("*chases cutely*"); + };*/ + }; + + if(typeof(pixel.charged) === "undefined") { + pixel.charged = false; + }; + + if(pixel.charge) { + pixel.charged = true; + }; + + var pX = pixel.x; + var pY = pixel.y; + + if(pixel.charged) { + var explosionRadius = 6; + if(!pixel.didChargeBlueTinted) { //do once, on initial charge + //console.log("something something halsey lyric"); + var color = pixel.color; + if(color.startsWith("rgb")) { + //console.log("rgb detected"); + color = color.split(","); //split color for addition + var red = parseFloat(color[0].substring(4)); + var green = parseFloat(color[1]); + var blue = parseFloat(color[2].slice(0,-1)); + red = rgbColorBound(red + 51); + green = rgbColorBound(green + 51); + blue = rgbColorBound(blue + 102); + color = `rgb(${red},${green},${blue})`; + pixel.color = color; + //console.log("color set"); + } else if(color.startsWith("hsl")) { + //console.log("hsl detected"); + color = color.split(","); //split color for addition + var hue = parseFloat(color[0].substring(4)); + var saturation = parseFloat(color[1].slice(0,-1)); + var luminance = parseFloat(color[2].slice(0,-2)); + hue = hue % 360; //piecewise hue shift + if(hue <= 235 && hue >= 135) { + hue = 185; + } else if(hue < 135) { + hue += 50; + } else if(hue > 235 && hue < 360) { + hue -= 50; + }; + saturation = slBound (saturation + 10); + luminance = slBound(luminance + 20); + color = `hsl(${hue},${saturation}%,${luminance}%)`; + pixel.color = color; + //console.log("color set"); + }; + pixel.didChargeBlueTinted = true; + }; + } else { + var explosionRadius = 4; //should be half of the original creeper's radius + }; + + if(pixel.burning) { + pixel.hissing = true; + if(!pixel.hissStart) { + pixel.hissStart = pixelTicks; + }; + if(!pixel.burnStart) { //I don't like errors. + pixel.burnStart = pixel.ticks; + }; + if(pixelTicks - pixel.burnStart > 15) { + //console.log("Kaboom?"); + explodeAt(pixel.x,pixel.y,explosionRadius); + //console.log("Yes, Rico, kaboom."); + }; + }; + + //Pre-explosion handler: keeps track of time before the kaboom + for(i = 0; i < 1; i++) { //dummy for loop + if(pixel.hissing) { + //console.log("Ssssssss"); + if(pixel.dead) { + //console.log("ss-- oof"); + pixel.hissing = false; + break; + }; + if(!pixel.hissStart) { + //console.log("t-30 ticks or whatever it was"); + pixel.hissStart = pixelTicks; + }; + //Color code { + var ticksHissing = pixelTicks - pixel.hissStart; + var color = pixel.color; //do on each hissing tick + if(color.startsWith("rgb")) { + //console.log("rgb detected"); + color = color.split(","); //split color for addition + var red = parseFloat(color[0].substring(4)); + var green = parseFloat(color[1]); + var blue = parseFloat(color[2].slice(0,-1)); + red = rgbColorBound(red + (2 * ticksHissing)); + green = rgbColorBound(green + (2 * ticksHissing)); + blue = rgbColorBound(blue + (2 * ticksHissing)); + color = `rgb(${red},${green},${blue})`; + pixel.color = color; + //console.log("color set"); + } else if(color.startsWith("hsl")) { + //console.log("hsl detected"); + color = color.split(","); //split color for addition + var hue = parseFloat(color[0].substring(4)); + var saturation = parseFloat(color[1].slice(0,-1)); + var luminance = parseFloat(color[2].slice(0,-2)); + luminance = slBound(luminance + (2 * 1.176)); + color = `hsl(${hue},${saturation}%,${luminance}%)`; + pixel.color = color; + //console.log("color set"); + }; + //} + + if(pixelTicks - pixel.hissStart > 15) { + //console.log("Kaboom?"); + //console.log(`Exploding with radius ${explosionRadius} (charged: ${pixel.charged})`); + explodeAt(pixel.x,pixel.y,explosionRadius); + //console.log("Yes, Rico, kaboom."); + }; + }; + }; + + if(Math.random() < 0.01) { //1% chance each tick to lose interest + pixel.following = false; + //console.log("Meh."); + }; + + //Human detection loop (looks ahead according to direction and sets the "following" variable to true, telling the body to lock the direction) + var directionAdverb = "left"; + if(pixel.dir > 0) { + directionAdverb = "right"; + }; + //console.log(`Looking ${directionAdverb}`) + if(pixel.dir === -1) { + for(i = -4; i < 4+1; i++) { + var oY = i; + //console.log(`Starting row look at row ${pY+oY}`) + for(j = (-1); j > (-16 - 1); j--) { + var oX = j; + var nX = pX+oX; + var nY = pY+oY; + if(outOfBounds(nX,nY)) { + //console.log(`Stopping row look at pixel (${nX},${nY}) due to OoB`) + break; + }; + if(isEmpty(nX,nY)) { + //console.log(`Skipping pixel (${nX},${nY}) (empty)`) + continue; + }; + if(!isEmpty(nX,nY,true)) { + var newPixel = pixelMap[nX][nY]; + var newElement = newPixel.element; + if(enemyHumanoidArray.includes(newElement)) { + //console.log(`Human part found at (${nX},${nY})`) + if(!newPixel.dead) { + pixel.following = true; + //console.log(`Human detected at (${nX},${nY})`) + //Start "hissing" if a human is close enough + if(pyth(pX,pY,nX,nY) <= 3.15) { //probably misapplying the tolerance from the MC Wiki line: "Creepers will chase after any player, as long as it is within a 16 block (±5%) radius" + pixel.hissing = true; + if(!pixel.hissStart) { + pixel.hissStart = pixelTicks; + }; + }; + }; + } else { + //console.log(`Stopping row look at pixel (${nX},${nY}) due to non-human pixel in the way`) + break; //can't see through humans + }; + }; + }; + }; + } else if(pixel.dir === 1) { + for(i = -4; i < 4+1; i++) { + var oY = i; + //console.log(`Starting row look at row ${pY+oY}`) + for(j = 1; j < 16 + 1; j++) { + var oX = j; + var nX = pX+oX; + var nY = pY+oY; + if(outOfBounds(nX,nY)) { + //console.log(`Stopping row look at pixel (${nX},${nY}) due to OoB`) + break; + }; + if(isEmpty(nX,nY)) { + //console.log(`Skipping pixel (${nX},${nY}) (empty)`) + continue; + }; + if(!isEmpty(nX,nY,true)) { + var newPixel = pixelMap[nX][nY]; + var newElement = newPixel.element; + if(enemyHumanoidArray.includes(newElement)) { + //console.log(`Human part found at (${nX},${nY})`) + if(!newPixel.dead) { + pixel.following = true; + //console.log(`Human detected at (${nX},${nY})`) + //Start "hissing" if a human is close enough + if(pyth(pX,pY,nX,nY) <= 3.15) { + pixel.hissing = true; + if(!pixel.hissStart) { + pixel.hissStart = pixelTicks; + }; + }; + break; + }; + } else { + //console.log(`Stopping row look at pixel (${nX},${nY}) due to non-human pixel in the way`) + break; + }; + }; + }; + }; + }; + }, + related: ["creeper"], + }; + //Angelic Creeper elements.angelic_creeper = { //let's get this one out of the way first