add first patch

This commit is contained in:
2026-07-31 10:34:32 +09:00
parent 03aac2e45e
commit b1cbc6c78d
6390 changed files with 547430 additions and 0 deletions
@@ -0,0 +1,24 @@
console.info("[SOCIETY] gnomeInteraction.js loaded");
ItemEvents.entityInteracted((e) => {
const { hand, player, item, level, target, server } = e;
if (player.isFake() || player.isCrouching()) return;
if (hand == "OFF_HAND") return;
if (target.type !== "minecraft:villager") return;
if (hand == "MAIN_HAND") {
if (item.id === "oreganized:silver_ingot") {
const { x, y, z } = target;
server.runCommandSilent(`playsound trials:breeze_idle block @a ${x} ${y} ${z} 0.2 1`);
let reward = player.level.createEntity("minecraft:item");
reward.x = player.x;
reward.y = player.y;
reward.z = player.z;
reward.item = Item.of(`2x society:fairy_dust`);
reward.spawn();
if (!player.isCreative()) item.shrink(1);
} else {
server.runCommandSilent(`dialog ${player.getUuid()} show ${player.username} gnome_unique_chatter_${Math.floor(Math.random() * 3)}`);
}
e.cancel()
}
});
@@ -0,0 +1,219 @@
console.info("[SOCIETY] npcInteraction.js loaded");
// These lengths are formed from generateNpcDialog.js
const dialogLengths = {
banker: { chatterLengths: [15.0, 20.0, 13.0, 9.0, 11.0, 18.0], giftResponseLengths: { loved: 9.0, liked: 8.0, neutral: 8.0, disliked: 12.0, hated: 16.0 } },
blacksmith: { chatterLengths: [16.0, 10.0, 13.0, 12.0, 11.0, 14.0], giftResponseLengths: { loved: 8.0, liked: 9.0, neutral: 8.0, disliked: 8.0, hated: 10.0 } },
carpenter: { chatterLengths: [11.0, 10.0, 13.0, 9.0, 9.0, 15.0], giftResponseLengths: { loved: 6.0, liked: 7.0, neutral: 8.0, disliked: 10.0, hated: 10.0 } },
fisher: { chatterLengths: [11.0, 9.0, 10.0, 10.0, 10.0, 11.0], giftResponseLengths: { loved: 7.0, liked: 6.0, neutral: 9.0, disliked: 7.0, hated: 7.0 } },
librarian: { chatterLengths: [5.0, 5.0, 5.0, 5.0, 5.0, 6.0], giftResponseLengths: { loved: 5.0, liked: 5.0, neutral: 5.0, disliked: 5.0, hated: 5.0 } },
market: { chatterLengths: [18.0, 14.0, 9.0, 16.0, 14.0, 14.0], giftResponseLengths: { loved: 10.0, liked: 8.0, neutral: 17.0, disliked: 12.0, hated: 13.0 } },
shepherd: { chatterLengths: [15.0, 14.0, 13.0, 12.0, 14.0, 17.0], giftResponseLengths: { loved: 9.0, liked: 10.0, neutral: 8.0, disliked: 8.0, hated: 11.0 } },
trader: { chatterLengths: [7.0, 5.0, 5.0, 7.0, 7.0, 6.0], giftResponseLengths: { loved: 5.0, liked: 5.0, neutral: 5.0, disliked: 5.0, hated: 5.0 } },
wise_oak: { chatterLengths: [7.0, 5.0, 5.0, 5.0, 5.0, 8.0], giftResponseLengths: { loved: 0.0, liked: 0.0, neutral: 0.0, disliked: 0.0, hated: 0.0 } },
witch: { chatterLengths: [7.0, 5.0, 6.0, 8.0, 6.0, 5.0], giftResponseLengths: { loved: 5.0, liked: 5.0, neutral: 5.0, disliked: 5.0, hated: 6.0 } },
}
const maxGifts = {
banker: "society:slouching_towards_artistry",
blacksmith: Item.of('justhammers:iron_hammer', "{Damage:0,RepairCost:0,display:{Name:'{\"text\":\"§6Aiden\\'s Hammer\"}'}}").enchant('minecraft:efficiency', 5).enchant('minecraft:fortune', 3),
carpenter: Item.of('portable_blueprints:worn_blueprint', '{Damage:1,allow_nbt:1,altezza:0,blueprint_name:"blockapedia",buildAnyway:0b,display:{Name:\'{"italic":false,"color":"#FFFF00","text":"Blueprint: Blockapedia"}\'},free_build:1,inventari_blocco_selezionati:"",lunghezzaX:0,lunghezzaZ:0,mirrowX:0b,mirrowY:0b,mirrowZ:0b,nome:"blockapedia",owner:"worn",owner_name:"Ace (Built by Mimsy)",remaining_uses:1,rotateValue:0s,skipObstructionBlock:0b,visualizeBuild:1b,wasHolding:1b,worn_set:1b}'),
fisher: "society:heart_of_neptunium",
market: "society:universal_methods_of_farming",
shepherd: Item.of('2x wildernature:penguin_spawn_egg'),
librarian: 'society:debt_caverns',
trader: "",
witch: "society:auto_petter",
}
const getNpcKey = (customName) => {
const startIndex = customName.indexOf("dialog.npc.");
const endIndex = customName.indexOf(".name");
if (startIndex === -1 || endIndex === -1 || endIndex <= startIndex) {
console.log("[SOCIETY] WARNING: NPC has no custom name!")
return;
}
return customName.substring(startIndex + "dialog.npc.".length, endIndex);
}
const npcIds = ["easy_npc:humanoid", "easy_npc:humanoid_slim"];
const handleNpc = (e, npcId, level, server, target, player, item) => {
let day = global.getDay(level);
if (!player.persistentData.npcData) player.persistentData.npcData = {}
let npcData = player.persistentData.npcData[npcId];
if (!npcData) {
if (!player.stages.has(`invited_${npcId}`)) {
player.stages.add(`invited_${npcId}`)
}
player.persistentData.npcData[npcId] = {
friendship: -1,
dayLastChatted: -1,
dayLastGifted: -4,
maxGifted: false
}
} else if (Number(npcData.friendship) == -1) {
npcData.friendship = 5
server.runCommandSilent(
`dialog ${player.getUuid()} show ${player.username} ${npcId}_intro`
);
} else if (!npcData.maxGifted && Number(npcData.friendship) >= 500) {
if (npcId.equals("banker") && player.stages.has("slouching_towards_artistry")) {
player.give(Item.of("2x waystones:waystone"))
server.runCommandSilent(`dialog ${player.username} show ${player.username} banker_unique__gift_read`);
} else if (npcId.equals("market") && player.stages.has("universal_methods_of_farming")) {
player.give(Item.of("16x society:sparkpod_seed"))
server.runCommandSilent(`dialog ${player.username} show ${player.username} market_unique_five_gift_read`);
} else if (npcId.equals("librarian") && player.stages.has("debt_caverns")) {
player.give(Item.of('botania:diva_charm'))
player.give(Item.of('botania:mana_ring', '{mana:500000}'))
server.runCommandSilent(`dialog ${player.username} show ${player.username} librarian_unique_five_gift_read`);
} else if (npcId.equals("trader")) {
player.stages.add("trader_clothing")
server.runCommandSilent(`dialog ${player.getUuid()} show ${player.username} ${npcId}_unique_five_gift`);
} else {
player.give(maxGifts[npcId])
server.runCommandSilent(`dialog ${player.getUuid()} show ${player.username} ${npcId}_unique_five_gift`);
}
npcData.maxGifted = true
} else {
// Carpenter has two shops so it always needs dialog to choose between the two.
let dialogNumber;
if (player.isCrouching() && item.hasTag("society:villager_gift")) {
if (npcId === "wise_oak") {
server.runCommandSilent(`dialog ${player.getUuid()} show ${player.username} wise_oak_unique_no_gifting`);
server.runCommandSilent(`playsound stardew_fishing:fish_escape block @a ${target.x} ${target.y} ${target.z}`);
server.runCommandSilent(`playsound species:item.wicked_swapper.teleport block @a ${target.x} ${target.y} ${target.z}`);
level.spawnParticles(
"mysticaloaktree:wind",
true,
target.x,
target.y + 1.5,
target.z,
0.2 * rnd(1, 2),
0.2 * rnd(1, 2),
0.2 * rnd(1, 2),
25,
0.001
);
return;
}
if (day > npcData.dayLastGifted + 3 || npcData.dayLastGifted - day > 1) {
let giftValue = global.getVillagerGiftResult(npcId, item.id);
dialogNumber = Math.floor(Math.random() * dialogLengths[npcId].giftResponseLengths[giftValue]);
let friendshipModification = 0;
switch (giftValue) {
case "hated":
friendshipModification = -30;
break;
case "disliked":
friendshipModification = -15;
break;
case "loved":
friendshipModification = 40;
break;
case "liked":
friendshipModification = 25;
break;
case "neutral":
default:
friendshipModification = 10;
break;
}
npcData.friendship = npcData.friendship + friendshipModification;
npcData.dayLastGifted = day
server.runCommandSilent(`playsound stardew_fishing:complete block @a ${target.x} ${target.y} ${target.z}`);
server.runCommandSilent(`playsound species:item.wicked_swapper.teleport block @a ${target.x} ${target.y} ${target.z}`);
level.spawnParticles(
"supplementaries:confetti",
true,
target.x,
target.y + 1.5,
target.z,
0.2 * rnd(1, 2),
0.2 * rnd(1, 2),
0.2 * rnd(1, 2),
25,
0.001
);
let delay = 0;
if (item.isEdible()) delay = 20
if (!player.isCreative()) item.shrink(1);
server.scheduleInTicks(delay, () => {
server.runCommandSilent(
`dialog ${player.getUuid()} show ${player.username} ${npcId}_gift_${giftValue}_${dialogNumber}`
);
});
if (Math.random() < 0.01) {
let newGolem = level.createEntity(Math.random() < 0.5 ? "golemoverhaul:barrel_golem" : "golemoverhaul:hay_golem");
newGolem.setX(target.getX() + 8);
newGolem.setY(target.getY() + 2);
newGolem.setZ(target.getZ() + -8);
newGolem.spawn();
}
} else {
player.tell(Text.translatable("society.npc.gifted_too_soon").gold())
}
} else {
if (global.compareDay(day, npcData.dayLastChatted, 1)) {
let hearts = Math.floor(npcData.friendship / 100);
dialogNumber = Math.floor(Math.random() * (dialogLengths[npcId].chatterLengths[hearts]));
server.runCommandSilent(
`dialog ${player.getUuid()} show ${player.username} ${npcId}_chatter_friendship${hearts}_${dialogNumber}`
);
npcData.dayLastChatted = day
if (npcData.friendship + 5 > 500) {
npcData.friendship = 500
} else {
if (npcId === "wise_oak") npcData.friendship = npcData.friendship + 15
npcData.friendship = npcData.friendship + 5
}
} else {
if (npcId === "carpenter") {
server.runCommandSilent(`dialog ${player.getUuid()} show ${player.username} carpenter_choice_dialog_need_to_buy`);
} else if (npcId === "librarian" && global.isLateSeason(level)) {
server.runCommandSilent(`dialog ${player.getUuid()} show ${player.username} librarian_choice_dialog_book_fair`);
} else if (npcId === "wise_oak") {
if (Number(npcData.friendship) >= 500) {
player.tell("opening shop")
server.runCommandSilent(`openshop ${player.username} wise_oak`)
}
} else {
server.runCommandSilent(`openshop ${player.username} ${npcId}`)
}
}
}
}
if (npcId === "wise_oak") {
if (['society:tapper', 'society:auto_tapper'].includes(item.id)) {
npcData.friendship = 0;
}
} else {
e.cancel()
}
}
ItemEvents.entityInteracted((e) => {
const { hand, player, item, level, target, server } = e;
if (player.isFake()) return;
if (hand == "OFF_HAND") return;
if (item.id == 'easy_npc_config_ui:easy_npc_wand') return;
if (!npcIds.includes(target.type)) return;
if (hand == "MAIN_HAND") {
let npcId = getNpcKey(target.nbt.CustomName.toString())
handleNpc(e, npcId, level, server, target, player, item)
}
});
BlockEvents.rightClicked("mysticaloaktree:wise_oak", (e) => {
const { hand, player, block, level, server, item } = e;
if (player.isFake()) return;
if (hand == "OFF_HAND") return;
if (hand == "MAIN_HAND") {
handleNpc(e, "wise_oak", level, server, block, player, item)
}
});
+31
View File
@@ -0,0 +1,31 @@
console.info("[SOCIETY] npcInvite.js loaded");
ItemEvents.rightClicked("society:invitation", (e) => {
const { server, player, item } = e;
if (player.isFake()) e.cancel();
const inviteNbt = player.getHeldItem("main_hand").getNbt();
if (inviteNbt) {
let id = inviteNbt.get("type").id
let baseId = id.substring(8, id.length);
server.scheduleInTicks(0, () => {
server.scheduleInTicks(1, () => {
player.give(Item.of("society:villager_home", `{type:"${baseId}"}`))
});
});
if (!player.stages.has(`invited_${baseId}`)) {
player.stages.add(`invited_${baseId}`)
player.tell(Text.translatable("society.invitation.place_home").green());
if (baseId === "market") {
player.tell(Text.translatable("society.new_villager.message").green());
}
}
if (!player.isCreative()) item.count--;
server.runCommandSilent(
`playsound stardew_fishing:complete block @a ${player.x} ${player.y} ${player.z}`
);
} else {
player.tell("Something went wrong! Tell Chakyl")
}
global.addItemCooldown(player, item, 4);
});
@@ -0,0 +1,161 @@
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")
}
}
}
});