Files
jgl_sunlit_patch/kubejs/server_scripts/npcs/villagerHomeMechanics.js
T
2026-07-31 10:34:32 +09:00

162 lines
5.3 KiB
JavaScript

console.info("[SOCIETY] villagerMechanics.js loaded");
const npcMap = new Map([
["carpenter", "humanoid/carpenter"],
["market", "humanoid/market"],
["blacksmith", "humanoid/blacksmith"],
["shepherd", "humanoid_slim/shepherd"],
["fisher", "humanoid_slim/fisher"],
["banker", "humanoid_slim/banker"],
["librarian", "humanoid_slim/librarian"],
["witch", "humanoid_slim/witch"],
["trader", "humanoid/trader"]
]);
const getBoundNpc = (level, block, boundNpc) => {
let nearbyNPCs = level.getLevel()
.getServer()
.getEntities()
.filter((entityType) => entityType.type === "easy_npc:humanoid" || entityType.type === "easy_npc:humanoid_slim");
let foundNpc = -1;
nearbyNPCs.forEach((e) => {
if (e.getUuid().toString() === boundNpc) {
foundNpc = e;
}
});
return foundNpc;
};
BlockEvents.placed("society:villager_home", (e) => {
const { player, block, level, server } = e;
if (player.isFake()) e.cancel();
const homeNbt = player.getHeldItem("main_hand").getNbt();
let nbt = block.getEntityData();
const { x, y, z } = block;
if (homeNbt) {
let villagerType = homeNbt.getString("type");
let day = global.getDay(level);
if (!player.persistentData.npcData) player.persistentData.npcData = {}
let npcData = player.persistentData.npcData[villagerType];
if (!npcData) {
player.persistentData.npcData[villagerType] = {
friendship: -1,
dayLastChatted: -1,
dayLastGifted: -4,
dayLastPlaced: -10,
maxGifted: false,
}
npcData = player.persistentData.npcData[villagerType];
}
if (!npcData.dayLastPlaced) npcData.dayLastPlaced = -10
if (day > Number(npcData.dayLastPlaced) + 10 || Number(npcData.dayLastPlaced) - day > 1) {
let nearbyNPCs = level
.getEntitiesWithin(AABB.ofBlock(block).inflate(4))
.filter((entityType) => entityType.type === "easy_npc:humanoid" || entityType.type === "easy_npc:humanoid_slim");
if (player && nearbyNPCs.length == 0) {
server.runCommandSilent(
`execute in ${level.dimension} run easy_npc preset import_new custom easy_npc:preset/${npcMap.get(
String(villagerType)
)}.npc.nbt ${x} ${y + 0.25} ${z}`
);
nearbyNPCs = level
.getEntitiesWithin(AABB.ofBlock(block).inflate(2))
.filter((entityType) => entityType.type === "easy_npc:humanoid" || entityType.type === "easy_npc:humanoid_slim");
level.spawnParticles(
"ribbits:spell",
true,
nearbyNPCs[0].x,
nearbyNPCs[0].y + 1.5,
nearbyNPCs[0].z,
0.2 * rnd(1, 2),
0.2 * rnd(1, 2),
0.2 * rnd(1, 2),
20,
0.05
);
server.runCommandSilent(
`playsound botania:starcaller block @a ${player.x} ${player.y} ${player.z}`
);
server.runCommandSilent(`easy_npc navigation set home ${nearbyNPCs[0].getUuid()} ${x} ${y + 0.25} ${z}`)
nbt.merge({
data: {
type: villagerType,
boundNpc: nearbyNPCs[0].getUuid().toString(),
placer: player.getUuid().toString(),
},
});
global.setBlockEntityData(block, nbt)
player.tell(
Text.translatable(
"society.villager_home.moved_in",
Text.translatable(`dialog.npc.${villagerType}.name`).gold()
)
);
npcData.dayLastPlaced = day
} else {
player.tell(Text.translatable("society.villager_home.too_close").red());
player.inventoryMenu.broadcastFullState();
e.cancel();
}
} else {
player.tell(Text.translatable("society.villager_home.recently_moved_in").red());
player.inventoryMenu.broadcastFullState();
e.cancel();
}
} else {
player.tell(Text.translatable("society.villager_home.error").red());
player.inventoryMenu.broadcastFullState();
e.cancel();
}
});
BlockEvents.broken("society:villager_home", (e) => {
const { block, player, level, server } = e;
let nbt = block.getEntityData();
const { type, placer, boundNpc } = nbt.data;
if (player.getUuid().toString() !== placer && placer != -1 && !player.isCreative()) {
player.tell(
Text.translatable(
"society.villager_home.not_invited_by_you",
Text.translatable(`dialog.npc.${type}.name`).gold()
).red()
);
e.cancel();
}
let foundNpc = getBoundNpc(level, block, boundNpc);
if (foundNpc != -1) {
foundNpc.setRemoved("unloaded_to_chunk");
level.spawnParticles(
"windswept:feather_cloak",
true,
foundNpc.x,
foundNpc.y + 1.5,
foundNpc.z,
0.2 * rnd(1, 2),
0.2 * rnd(1, 2),
0.2 * rnd(1, 2),
20,
0.05
);
server.runCommandSilent(
`playsound windswept:block.pinecone.note block @a ${player.x} ${player.y} ${player.z}`
);
player.tell(
Text.translatable(
"society.villager_home.moved_out",
Text.translatable(`dialog.npc.${type}.name`).gold()
)
);
block.popItem(Item.of(block.id, `{type:${type}}`));
player.persistentData.npcData[type].dayLastPlaced = -10
} else {
if (!(type == undefined || placer == undefined || boundNpc == undefined)) {
if (!player.isCreative()) {
e.cancel();
} else {
player.tell("Unbound villager to home! If the villager still exists, run /easy_npc delete @e")
}
}
}
});