From c17eb932c0c5020eea51019e83958741534494d6 Mon Sep 17 00:00:00 2001 From: voidapex11 <154328367+voidapex11@users.noreply.github.com> Date: Wed, 15 Jan 2025 10:45:16 +0000 Subject: [PATCH] add guided_rocket.js --- mod-list.html | 1 + mods/guided_rocket.js | 106 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 mods/guided_rocket.js diff --git a/mod-list.html b/mod-list.html index 350a4ce8..c00ede85 100644 --- a/mod-list.html +++ b/mod-list.html @@ -249,6 +249,7 @@ Weapons aircrafts.jsAdds aircraft and aircraft part pixelsJayd c_fighter_jet.jsAdds a controllable fighter jet, wasd to move, q+wasd to shoot, gvbn for missiles.Jayd +guided_rocket.jsAdds a homing misile.voidapex11 icb.jsAdds various levels of nested cluster bombsAlice life_eater.jsAdds Warhammer 40,000’s Life-Eater Virus and Virus BombsAlice liquid_void.jsAdds a liquid variant of VoidAlice diff --git a/mods/guided_rocket.js b/mods/guided_rocket.js new file mode 100644 index 00000000..9d6258c5 --- /dev/null +++ b/mods/guided_rocket.js @@ -0,0 +1,106 @@ +// from code_libary.js +function pyth(xA, yA, xB, yB) { + var a = Math.abs(xB - xA); + var b = Math.abs(yB - yA); + var c = Math.sqrt(a ** 2 + b ** 2); + return c; +}; +tgt = "" + +elements.guided_misile = { + color: "#323333", + category: "weapons", + behavior: [ + "EX:10|EX:10|EX:10", + "EX:10| XX |EX:10", + "EX:10|EX:10|EX:10", + ], + onSelect: function () { + var answer1 = prompt("Please input the target element.", (tgt || undefined)); + if (!answer1) { return } + tgt = answer1; + }, + tick: (pixel) => { + let targets = []; + + // find all posible targets + for (var x = 1; x < width; x++) { + for (var y = 1; y < height; y++) { + if (!isEmpty(x, y)) { + if (pixelMap[x][y]["element"] === tgt) { + pxl = pixelMap[x][y]; + targets.push( + [pxl.x, pxl.y, + // calculate distance from target to current pixel + pyth(pixel.x, pixel.y, pxl.x, pxl.y) + ]); + } + } + } + } + + if (targets == []) { + return + } + + // sort the targets by distance from self + targets.sort((a, b) => a[2] - b[2]); + + try { + // get the closest target + current_best = targets[0]; + + target = [current_best[0], current_best[1]]; + } catch { + // no pixels of target found + return + } + + if (pixel.x != target[0] || pixel.y != target[1]) { + let { x, y } = pixel; + const empty = checkForEmptyPixels(x, y); + const [tX, tY] = target; + + // Separate moves into non-diagonal and diagonal categories + const nonDiagonal = []; + const diagonal = []; + + for (const [dx, dy] of empty) { + if ((dx === 0) || (dy === 0)) { + nonDiagonal.push([dx, dy]); // Horizontal or vertical moves + } else { + diagonal.push([dx, dy]); // Diagonal moves + } + } + + let prioritizedMoves = [] + + // chose whether to move diagonaly + if (Math.abs(Math.abs(x - tX) - Math.abs(y - tY)) > 1) { + prioritizedMoves = [...nonDiagonal]; + } else { + prioritizedMoves = [...diagonal]; + } + + let bestVal = pyth(tX, tY, x, y) + Math.sqrt(Math.pow(tX - x, 2) + Math.pow(tY - y, 2)); + let best = null; + + for (const [dx, dy] of prioritizedMoves) { + const x_ = x + dx; + const y_ = y + dy; + const c = Math.sqrt(Math.pow(tX - x_, 2) + Math.pow(tY - y_, 2)); + if (c < bestVal) { + bestVal = c; + best = [dx, dy]; + } + } + + if (best) { + if (!tryMove(pixel, x + best[0] * 2, y + best[1] * 2, undefined, true)) { + tryMove(pixel, x + best[0], y + best[1], undefined, true) + }; + } + } + } +} \ No newline at end of file