Skip to content

Commit

Permalink
Merge pull request #10 from Adr-hyng/main
Browse files Browse the repository at this point in the history
Revision cleaning update
  • Loading branch information
Adr-hyng authored Aug 3, 2023
2 parents f509b63 + a222d05 commit a245110
Show file tree
Hide file tree
Showing 58 changed files with 1,351 additions and 510 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
node_modules/
package-lock.json
changelog.md
builds/
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
75 changes: 75 additions & 0 deletions BP/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{
"format_version": 2,
"header": {
"name": "Lumber Axe Addon BP: Chopping made easy! 1.0.5",
"description": "Cut the whole tree with easy as a lumberjack's pie! We create addons/datapack that will ease your survival plays. \n @Created By: @h_YanG_0A & @Brilliant",
"uuid": "4538bab6-a78b-4710-89e5-a2e103e97a6a",
"version": [
1,
0,
5
],
"min_engine_version": [
1,
20,
10
]
},
"modules": [
{
"description": "item and entity definitions",
"type": "data",
"uuid": "f0bc63f7-f2b2-4de2-a27c-6a3d5ac7cee4",
"version": [
1,
0,
0
]
},
{
"description": "scripts",
"type": "script",
"language": "javascript",
"uuid": "9717780a-c69f-4679-bbe6-dbf6dfcdd7de",
"version": [
1,
0,
5
],
"entry": "scripts/main.js"
}
],
"capabilities": [
"script_eval"
],
"dependencies": [
{
"module_name": "@minecraft/server",
"version": "1.4.0-beta"
},
{
"module_name": "@minecraft/server-ui",
"version": "1.2.0-beta"
},
{
"module_name": "@minecraft/server-admin",
"version": "1.0.0-beta"
},
{
"uuid": "62b4cab4-fa42-405b-bff6-1f47b6958dd6",
"version": [
1,
0,
5
]
}
],
"metadata": {
"authors": [
"@h_YanG_0A",
"@Brilliant"
],
"license": "GPL-3.0-or-later",
"url": "https://twitter.com/h_YanG_0A"
}
}
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
34 changes: 34 additions & 0 deletions BP/scripts/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export default {
/**
* Enables debug messages to content logs.
*/
debug: false,
/**
* Lumber Axe durability damage per log destroyed.
*/
durabilityDamagePerBlock: 3,
/**
* 1500 above is not recommended. It Does work but it's not recommended.
*/
chopLimit: 300,
/**
* Included blocks for custom logs, but any custom or vanilla logs also work as long as the block identifier ends with "*_log".
* Check: https://github.com/mcbe-mods/Cut-tree-one-click by Lete114.
*/
includedLog: [],
/**
* Excluded blocks for block logs you don't want to be included in being chopped.
*
* Tip:
* - excludedLog is prioritized over includedLog.
* - It's unnecessary to include log blocks that have "*_log" in their block id.
*/
excludedLog: [],
/**
* Disables the watchDogTerminate Log message. If true, it will only show a warning message when you enable content-ui log in the Minecraft settings.
*/
disableWatchDogTerminateLog: true,
};

// version (do not change)
export const VERSION = "1.0.5";
126 changes: 126 additions & 0 deletions BP/scripts/functions/tree_utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { EntityEquipmentInventoryComponent, EquipmentSlot, ItemLockMode, ItemStack, MinecraftBlockTypes } from "@minecraft/server";
import { validLogBlocks, axeEquipments, isGameModeSurvival, stackDistribution, durabilityDamagePerBlock, excludedLog, includedLog, chopLimit } from "../index";
async function treeCut(player, dimension, location, blockTypeId) {
const equipment = player.getComponent(EntityEquipmentInventoryComponent.componentId);
const currentHeldAxe = equipment.getEquipment(EquipmentSlot.mainhand);
if (!axeEquipments.includes(currentHeldAxe?.typeId))
return;
if (!isLogIncluded(blockTypeId))
return;
const isSurvivalMode = isGameModeSurvival(player);
if (!isSurvivalMode)
return;
if (isSurvivalMode)
currentHeldAxe.lockMode = ItemLockMode.slot;
const itemDurability = currentHeldAxe.getComponent('minecraft:durability');
const enchantments = currentHeldAxe.getComponent('minecraft:enchantments').enchantments;
const level = enchantments.hasEnchantment('unbreaking');
const unbreakingMultiplier = (100 / (level + 1)) / 100;
const unbreakingDamage = durabilityDamagePerBlock * unbreakingMultiplier;
const visited = await getTreeLogs(dimension, location, blockTypeId, (itemDurability.maxDurability - itemDurability.damage) / unbreakingDamage);
const totalDamage = visited.size * unbreakingDamage;
const postDamagedDurability = itemDurability.damage + totalDamage;
if (postDamagedDurability + 1 === itemDurability.maxDurability) {
equipment.setEquipment(EquipmentSlot.mainhand, undefined);
}
else if (postDamagedDurability > itemDurability.maxDurability) {
currentHeldAxe.lockMode = ItemLockMode.none;
return;
}
else if (postDamagedDurability < itemDurability.maxDurability) {
itemDurability.damage = itemDurability.damage + totalDamage;
currentHeldAxe.lockMode = ItemLockMode.none;
equipment.setEquipment(EquipmentSlot.mainhand, currentHeldAxe.clone());
}
for (const group of groupAdjacentBlocks(visited)) {
const firstElement = JSON.parse(group[0]);
const lastElement = JSON.parse(group[group.length - 1]);
if (firstElement === lastElement) {
await new Promise((resolve) => {
dimension.getBlock(firstElement).setType(MinecraftBlockTypes.air);
resolve();
});
continue;
}
else {
await new Promise((resolve) => {
dimension.fillBlocks(firstElement, lastElement, MinecraftBlockTypes.air);
resolve();
});
}
}
for (const group of stackDistribution(visited.size)) {
await new Promise((resolve) => {
dimension.spawnItem(new ItemStack(blockTypeId, group), location);
resolve();
});
}
}
function isLogIncluded(blockTypeId) {
if (excludedLog.includes(blockTypeId) || blockTypeId.includes('stripped_'))
return false;
if (includedLog.includes(blockTypeId) || validLogBlocks.test(blockTypeId))
return true;
return false;
}
async function getTreeLogs(dimension, location, blockTypeId, maxNeeded) {
const visited = new Set();
let queue = getBlockNear(dimension, location);
while (queue.length > 0) {
if (visited.size >= chopLimit || visited.size >= maxNeeded) {
return visited;
}
const _block = queue.shift();
if (!_block || !isLogIncluded(_block?.typeId))
continue;
if (_block.typeId !== blockTypeId)
continue;
const pos = JSON.stringify(_block.location);
if (visited.has(pos))
continue;
visited.add(pos);
queue.push(...getBlockNear(dimension, _block.location));
}
queue = [];
return visited;
}
function getBlockNear(dimension, location, radius = 1) {
const centerX = location.x;
const centerY = location.y;
const centerZ = location.z;
const positions = [];
let _block;
for (let x = centerX - radius; x <= centerX + radius; x++) {
for (let y = centerY - radius; y <= centerY + radius; y++) {
for (let z = centerZ - radius; z <= centerZ + radius; z++) {
if (centerX === x && centerY === y && centerZ === z)
continue;
_block = dimension.getBlock({ x, y, z });
if (_block.isAir())
continue;
positions.push(_block);
}
}
}
return positions;
}
function groupAdjacentBlocks(visited) {
const array = Array.from(visited).map(item => JSON.parse(item));
array.sort((a, b) => a.x - b.x || a.z - b.z || a.y - b.y);
const groups = [];
let currentGroup = [];
for (let i = 0; i < array.length; i++) {
if (i === 0 || (array[i].x === array[i - 1].x && array[i].z === array[i - 1].z && Math.abs(array[i].y - JSON.parse(currentGroup[currentGroup.length - 1]).y) <= 2)) {
currentGroup.push(JSON.stringify(array[i]));
}
else {
groups.push(currentGroup);
currentGroup = [JSON.stringify(array[i])];
}
}
if (currentGroup.length > 0) {
groups.push(currentGroup);
}
return groups;
}
export { treeCut, isLogIncluded, getTreeLogs };
26 changes: 26 additions & 0 deletions BP/scripts/functions/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { GameMode, system } from "@minecraft/server";
import { FormCancelationReason } from "@minecraft/server-ui";
function stackDistribution(number, groupSize = 64) {
const fullGroupsCount = Math.floor(number / groupSize);
const remainder = number % groupSize;
const groups = new Array(fullGroupsCount).fill(groupSize);
if (remainder > 0) {
groups.push(remainder);
}
return groups;
}
function isGameModeSurvival(player) {
return player.dimension.getPlayers({ gameMode: GameMode.survival, name: player.name, location: player.location, maxDistance: 1, closest: 1 }).length > 0;
}
async function forceShow(player, form, timeout = Infinity) {
const startTick = system.currentTick;
while ((system.currentTick - startTick) < timeout) {
const response = await (form.show(player)).catch(er => console.error(er, er.stack));
if (response.cancelationReason !== FormCancelationReason.UserBusy) {
return response;
}
}
;
throw new Error(`Timed out after ${timeout} ticks`);
}
export { isGameModeSurvival, stackDistribution, forceShow };
7 changes: 7 additions & 0 deletions BP/scripts/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from './functions/utils';
export * from './functions/tree_utils';
import Configuration from "./config";
const { durabilityDamagePerBlock, chopLimit, includedLog, excludedLog, disableWatchDogTerminateLog } = Configuration;
export { durabilityDamagePerBlock, chopLimit, includedLog, excludedLog, disableWatchDogTerminateLog };
export const validLogBlocks = /(_log|crimson_stem|warped_stem)$/;
export const axeEquipments = ["yn:wooden_lumber_axe", "yn:stone_lumber_axe", "yn:iron_lumber_axe", "yn:diamond_lumber_axe", "yn:golden_lumber_axe", "yn:netherite_lumber_axe"];
Loading

0 comments on commit a245110

Please sign in to comment.