veinminer mod

This commit is contained in:
ZXMushroom63 2025-04-27 19:01:01 +08:00
parent a5534d87cd
commit 5d856c5437

132
examplemods/veinminer.js Normal file
View File

@ -0,0 +1,132 @@
(function TreeChopperMod() {
ModAPI.meta.title("Vein Miner");
ModAPI.meta.description("Vein-mines trees & ores while crouching. Press the 'config' button for settings.");
ModAPI.meta.credits("By ZXMushroom63");
ModAPI.meta.version("v1.0");
globalThis.VEINMINERCONF = {
doLogs: true,
doOres: true,
doGravel: false,
doClay: false,
};
try {
Object.assign(conf, JSON.parse(localStorage.getItem("trc_mod::conf") || "{}"));
} catch (error) {
//swallow
}
ModAPI.meta.config(()=>{
var conf = document.createElement("div");
conf.innerHTML = `
<h1>Vein Miner Settings&nbsp;<a href="javascript:void(0)" onclick="this.parentElement.parentElement.remove()" style="color:red">[X]</a></h1>
<sub>Refresh page to apply settings</sub><br>
<label>Veinmine Logs: </label><input type=checkbox ${VEINMINERCONF.doLogs ? "checked" : ""} oninput="VEINMINERCONF.doLogs = this.checked; this.parentElement.__save();"></input><br>
<label>Veinmine Ores: </label><input type=checkbox ${VEINMINERCONF.doOres ? "checked" : ""} oninput="VEINMINERCONF.doOres = this.checked; this.parentElement.__save();"></input><br>
<label>Veinmine Gravel: </label><input type=checkbox ${VEINMINERCONF.doGravel ? "checked" : ""} oninput="VEINMINERCONF.doGravel = this.checked; this.parentElement.__save();"></input><br>
<label>Veinmine Clay: </label><input type=checkbox ${VEINMINERCONF.doClay ? "checked" : ""} oninput="VEINMINERCONF.doClay = this.checked; this.parentElement.__save();"></input><br>
`;
conf.style = "position: fixed; background-color: white; color: black; width: 100vw; height: 100vh; z-index: 256;top:0;left:0;";
conf.__save = ()=>localStorage.setItem("trc_mod::conf", JSON.stringify(VEINMINERCONF));
document.body.appendChild(conf);
});
ModAPI.dedicatedServer.appendCode(`globalThis.VEINMINERCONF = ${JSON.stringify(VEINMINERCONF)};`);
ModAPI.dedicatedServer.appendCode(function () {
ModAPI.addEventListener("bootstrap", () => {
const targettedBlockIds = [];
if (VEINMINERCONF.doLogs) {
targettedBlockIds.push("log", "log2");
}
if (VEINMINERCONF.doOres) {
targettedBlockIds.push("coal_ore", "gold_ore", "iron_ore", "lapis_ore", "quartz_ore", "diamond_ore", "emerald_ore", "redstone_ore", "lit_redstone_ore");
}
if (VEINMINERCONF.doGravel) {
targettedBlockIds.push("gravel");
}
if (VEINMINERCONF.doClay) {
targettedBlockIds.push("clay");
}
console.log(targettedBlockIds);
const valid_log_blocks = targettedBlockIds.map(x => ModAPI.blocks[x].getRef());
function stringifyBlockPos(blockPos) {
return blockPos.x + "," + blockPos.y + "," + blockPos.z;
}
function getNeighbors(blockPos) {
return [
//direct neighbors
blockPos.down(1),
blockPos.up(1),
blockPos.north(1),
blockPos.south(1),
blockPos.east(1),
blockPos.west(1),
//edges
blockPos.down(1).north(1),
blockPos.down(1).south(1),
blockPos.down(1).east(1),
blockPos.down(1).west(1),
blockPos.up(1).north(1),
blockPos.up(1).south(1),
blockPos.up(1).east(1),
blockPos.up(1).west(1),
blockPos.north(1).east(1),
blockPos.north(1).west(1),
blockPos.south(1).east(1),
blockPos.south(1).west(1),
//corners
blockPos.down(1).north(1).east(1),
blockPos.down(1).north(1).west(1),
blockPos.down(1).south(1).east(1),
blockPos.down(1).south(1).west(1),
blockPos.up(1).north(1).east(1),
blockPos.up(1).north(1).west(1),
blockPos.up(1).south(1).east(1),
blockPos.up(1).south(1).west(1),
];
}
async function getBlockGraph(blockPos, getBlockState, targetType) {
const closed = [stringifyBlockPos(blockPos)];
const logs = [];
const open = [...getNeighbors(blockPos)];
const maxIters = 120;
var i = 0;
while (open.length > 0 && i < maxIters) {
const target = open.pop();
closed.push(stringifyBlockPos(target));
i++;
const iBlockState = await getBlockState(target.getRef());
if (iBlockState.block.getRef() === targetType) {
logs.push(target);
open.push(...getNeighbors(target).filter(x => !closed.includes(stringifyBlockPos(x))));
}
}
return logs;
}
valid_log_blocks.forEach(b => {
const originalHarvest = b.$harvestBlock;
b.$harvestBlock = function ($theWorld, $player, $blockpos, $blockstate, $tileentity) {
if ($player.$isSneaking() && !ModAPI.util.isCritical()) {
ModAPI.promisify(async () => {
var player = ModAPI.util.wrap($player);
var world = ModAPI.util.wrap($theWorld);
var harvestCall = ModAPI.promisify(player.theItemInWorldManager.tryHarvestBlock);
const blocks = await getBlockGraph(ModAPI.util.wrap($blockpos), ModAPI.promisify(world.getBlockState), b);
for (let i = 0; i < blocks.length; i++) {
await harvestCall(blocks[i].getRef());
}
})();
}
originalHarvest.apply(this, [$theWorld, $player, $blockpos, $blockstate, $tileentity]);
}
});
});
});
})();