截图
介绍
This is an addon exposing Easy NPC’s public API to KubeJS scripts. This mod includes a preset NPC that is stored at data/kubejs_easynpc/easy_npc/preset/guide.npc.snbt, which is used in the following example.
Quick Start Example:
// Copy to kubejs/server_scripts/easynpc.js, then join/rejoin the world.
// A persistent per-player UUID prevents creating another guide on each login.
PlayerEvents.loggedIn(event => {
let player = event.player
if (player.persistentData.contains('kjsenGuide')) return
let npc = EasyNPC.spawn(player.serverLevel(),
'kubejs_easynpc:easy_npc/preset/guide.npc.snbt',
player.x + 2, player.y, player.z,
EasyNPC.spawnOptions().type('data').owner(player).identifier('example:guide'))
player.persistentData.putString('kjsenGuide', String(npc.uuid))
})
EasyNPCEvents.scriptAction(event => {
let player = event.player
if (player == null) return // Some actions have no initiating player.
switch (String(event.details.key)) {
case 'example:greet':
event.npc.getActions().getMessage().sendTo(player, 'This message came from KubeJS.')
let visits = event.npc.getActions().getState().get('example:visits')
event.npc.getActions().getState().setNumber('example:visits', (visits == null ? 0 : visits.asNumber()) + 1)
break
case 'example:follow':
event.npc.getObjectives().add('FOLLOW_OWNER')
break
case 'example:stop':
event.npc.getObjectives().remove('FOLLOW_OWNER')
break
}
})
EasyNPCEvents.stateChanged(event => {
console.info(`[EasyNPC] ${event.npc.uuid}: ${event.details.stateId} changed`)
})
For a more sophisticated example, check this.
NPCHandle
NPCHandle is a KubeJS container to call various methods involving the NPC entity.
Methods to construct or query
| Method | Usage |
|---|---|
EasyNPC.get(server, uuid) |
To build an NPCHandle. It does not gurantee the NPC exists. |
EasyNPC.findLoaded(server, uuid) |
return the NPCHanlde if the npc is loaded, otherwise null |
npc.exists() |
return true if the Easy NPC exists |
npc.isLoaded() |
return true if the Easy NPC is loaded |
npc.getEntity() |
get the NPC entity; null if not loaded |
EasyNPC.findByIdentifier(server, id) |
get a list of UUIDs that matches the id |
Methods to respawn, despawn or delete
| Method | Usage |
|---|---|
npc.respawn(level) |
Respawn the loaded NPC through Easy NPC’s respawn process. Return true if the operation succeeded. |
npc.despawn() |
Despawn the loaded NPC with the removal reason DESPAWNED. |
npc.despawnWithReason(reason) |
Despawn the the NPC with the specified NPCRemovalReason. |
npc.delete(level) |
Delete the NPC through Easy NPC’s deletion process. Return true if the operation succeeded. |
Methods to access handlers
| Method | Usage |
|---|---|
npc.getAttributes() |
Return the handler for combat, movement, interaction, environmental, inventory, display and Minecraft attributes. |
npc.getActions() |
Return the handler group for actions, movement, state, messages, dialogs, sounds and display operations. |
npc.getObjectives() |
Return the handler to manage NPC objectives. |
npc.getPause() |
Return the handler for pausing and resuming NPC behavior. |
npc.getMotion() |
Return the handler for snapping to a position, facing a position and moving in individual steps. |
npc.getPreset() |
Return the handler for creating preset items, obtaining export data and exporting WORLD presets. |
npc.getShoulder() |
Return the handler for shoulder mounting and related methods. |
npc.getPose() |
Return the handler for managing model poses. |
npc.getDialog() |
Return the handler for managing NPC dialog. |
npc.getTrading() |
Return the handler for managing NPC Trading. |
npc.getInventory() |
Return the handler for the NPC’s storage slots, including inserting and extracting items. |
npc.getEquipment() |
Return the handler for reading and changing held items and armor. |
KubeJS Server Events
The following events should be used in server_scripts. They are only used to notify occurrence and are not cancellable.
| Common Fields | Comment |
|---|---|
npc |
NPCHandle |
entity |
The entity involved in the event. |
level/server |
ServerLevel/MinecraftServer |
player |
The player involved in the event. Nullable |
audience |
audience list in the context |
eventType |
ActionEventType of the evnt |
details |
event-specific details |
| Event | event.details |
| —————————- | ———————— |
EasyNPCEvents.spawned |
none |
EasyNPCEvents.removed |
reason:NPCRemovalReason |
EasyNPCEvents.dialogOpened |
dialogId、label |
EasyNPCEvents.actionExecuted |
actionType、command |
EasyNPCEvents.stateChanged |
stateId、previous、current |
EasyNPCEvents.scriptAction |
key、arguments |
KubeJS Startup Event
EasyNPCStartupEvents.registerObjective registers custom Easy NPC AI objectives from KubeJS scripts. The script should be placed in startup_scripts. Restart the game or server after changing registrations.
Event methods
| Method | Usage |
|---|---|
event.register(id, factory) |
Register an objective using a factory that returns a Minecraft Goal. The id should be a namespaced string, such as kubejs:celebrate. The factory receives an NPCHandle and an ObjectiveDataEntry. It must return a new Goal instance. |
event.registerConfigured(id, definition) |
Register an objective with additional settings provided by ScriptObjectiveBuilder. |
event.isRegistered(id) |
Return true if the objective ID is already registered. |
Basic registration
// kubejs/startup_scripts/custom_objectives.js
EasyNPCStartupEvents.registerObjective(event => {
event.register('example:periodic_greeting', (npc, data) => {
let ticks = 0
return ScriptGoalBuilder.create()
.canUse(() => npc.isLoaded())
.canContinueToUse(() => npc.isLoaded())
.requiresUpdateEveryTick(() => true)
.tick(() => {
ticks++
if (ticks % 200 != 0) return
npc.getActions().getMessage().showBubble('Hello!')
})
.build()
})
})
This goal displays a speech bubble every 200 ticks (10 seconds) while running.
Configured registration
Use ScriptObjectiveBuilder to configure priority, compatibility, travel classification or a target goal.
// kubejs/startup_scripts/custom_objectives.js
EasyNPCStartupEvents.registerObjective(event => {
event.registerConfigured(
'example:periodic_greeting',
ScriptObjectiveBuilder.create()
.defaultPriority(5)
.hasTravelObjective(false)
.isCompatible(npc => npc.getDialog().isSupported())
.goal((npc, data) => {
let ticks = 0
return ScriptGoalBuilder.create()
.canUse(() => npc.isLoaded())
.canContinueToUse(() => npc.isLoaded())
.requiresUpdateEveryTick(() => true)
.tick(() => {
ticks++
if (ticks % 200 != 0) return
npc.getActions().getMessage().showBubble('Hello!')
})
.build()
})
)
})
ScriptGoalBuilder methods
ScriptGoalBuilder creates a Minecraft Goal using JavaScript callbacks.
| Method | Usage |
|---|---|
ScriptGoalBuilder.create() |
Create a goal builder. |
.canUse(() =>; boolean) |
Determine whether the goal can start. Required. |
.canContinueToUse(() =>; boolean) |
Determine whether the running goal can continue. Defaults to calling canUse(). |
.isInterruptable(() =>; boolean) |
Determine whether another goal can interrupt this goal. Defaults to true. |
.requiresUpdateEveryTick(() =>; boolean) |
Request updates every tick while the goal is running. Defaults to false. |
.start(() =>; {}) |
Run when the goal starts. |
.tick(() =>; {}) |
Run when the goal receives an update while active. |
.stop(() =>; {}) |
Run when the goal stops. |
.flags(names) |
Declare the AI resources used by the goal: MOVE, LOOK, JUMP or TARGET. Defaults to no flags. |
.build() |
Create the Goal instance. |
Adding the objective to an NPC
After registration, add an entry to an NPC from a server-side callback:
// Call this function with a loaded NPCHandle.
function enablePeriodicGreeting(npc) {
let objectives = npc.getObjectives()
let id = 'example:periodic_greeting'
if (!objectives.has(id)) {
objectives.addEntry(objectives.createCustomEntry(id))
}
}
You can then query, reprioritize or remove it:
npc.getObjectives().has('example:periodic_greeting')
npc.getObjectives().setPriority('example:periodic_greeting', 3)
npc.getObjectives().remove('example:periodic_greeting')
EasyNPC Binding
EasyNPC is a binding available in server_scripts. It provides methods for spawning and finding NPCs, working with presets, and creating action and condition data.
Methods to spawn or find NPCs
| Method | Usage |
|---|---|
EasyNPC.spawn(level, preset, x, y, z) |
Spawn an NPC from a preset and return its NPCHandle. Uses the DATA preset source by default. |
EasyNPC.spawn(level, preset, x, y, z, options) |
Spawn an NPC using the supplied SpawnOptions. |
EasyNPC.get(server, uuid) |
Create an NPCHandle for a UUID. This does not guarantee that the NPC exists or is loaded. |
EasyNPC.findLoaded(server, uuid) |
Return an NPCHandle if the NPC is loaded; otherwise, return null. |
EasyNPC.findByIdentifier(server, id) |
Return a list of NPC UUIDs matching the custom identifier. This does not load their entities. |
Spawning throws an exception if the preset cannot be used or the requested UUID is already registered. Use the existing handle’s restore or revive methods for an existing NPC.
Spawn options
EasyNPC.spawnOptions() creates a reusable options builder.
| Method | Usage |
|---|---|
EasyNPC.spawnOptions() |
Create spawn options with the preset source set to DATA. |
options.type(type) |
Set the preset source. Client-local LOCAL presets are not supported by this server-side binding. |
options.uuid(uuid) |
Set the NPC UUID. If omitted, each spawn generates a random UUID. |
options.owner(player) |
Set the owning ServerPlayer. |
options.identifier(id) |
Set a custom identifier, such as example:guide. An identifier does not enforce uniqueness. |
options.getType() |
Return the preset source. |
options.getUuid() |
Return the configured UUID, or null if unspecified. |
options.getOwner() |
Return the configured owner, or null. |
options.getIdentifier() |
Return the configured identifier, or null. |
Methods to create actions
| Method | Usage |
|---|---|
EasyNPC.action(type) |
Create an ActionDataEntry with the specified Easy NPC ActionDataType. |
EasyNPC.scriptAction(key) |
Create a custom action that triggers EasyNPCEvents.scriptAction with the supplied key. |
EasyNPC.scriptActionWithArgs(key, arguments) |
Create a script action with a key and a list of string arguments. |
EasyNPC.actionSet(entries) |
Create an ActionDataSet containing the supplied action entries. |
Script action keys and arguments must be non-empty tokens without whitespace.
Methods to create conditions
| Method | Usage |
|---|---|
EasyNPC.condition(type) |
Create a ConditionDataEntry using an Easy NPC ConditionType. |
EasyNPC.customCondition(id) |
Create a condition entry referencing a custom condition ID. |
EasyNPC.conditionSet(entries) |
Create a ConditionDataSet containing the supplied condition entries. |
Methods to create action contexts
An ActionContext contains information about how an action was triggered, including its initiator and audience.
| Method | Usage |
|---|---|
EasyNPC.actionContext() |
Return the empty context, with no initiator or audience. |
EasyNPC.actionContextFor(player) |
Create a context with the supplied player as its initiator and single-member audience. |
Methods to query or delete presets
| Method | Usage |
|---|---|
EasyNPC.listPresets(server, type) |
Return preset resource IDs from the specified server-side source, sorted by ID. |
EasyNPC.presetExists(server, type, id) |
Check whether a preset exists. This can also check presets hidden from catalog listings. |
EasyNPC.deleteWorldPreset(server, id) |
Delete a WORLD preset file and return a PresetFileResult. |
listPresets() and presetExists() reject the client-local LOCAL source.
A preset missing from listPresets() is not necessarily absent: it may be hidden from listings.
DATA preset IDs
For a file at:
data/example/easy_npc/preset/merchant.npc.snbt
Use:
example:easy_npc/preset/merchant.npc.snbt
WORLD preset IDs
WORLD file operations require this format:
easy_npc:preset/<path>.nbt
easy_npc:preset/<path>.snbt
常见问题
KubeJS Easy NPC 支持哪些 Minecraft 版本?
KubeJS Easy NPC 支持 Minecraft Java 版 1.20.1–1.21.1,共 2 个版本,可用的加载器:Forge / NeoForge。下载时注意选择和你游戏版本一致的文件。
KubeJS Easy NPC 怎么安装?
先用 PCL2 或 HMCL 启动器安装对应版本的 Forge / NeoForge,再把下载的 .jar 文件放进游戏目录的 mods 文件夹,重新启动游戏即可。开启了版本隔离的,mods 文件夹在 versions/版本名 下面。
vomiter 的其他作品
查看全部 →Farmer’s Delight Addon Fixes
修复 My Nether's Delight 1.8 与 Farmer's Delight 1.3+ 的兼容性问题;同时支持 Miners Delight+ 和 Dungeons Delight。
DamageSource Is Not Null Plus
尝试修复“NullPointerException:LivingDeathEvent.getSource() 返回 null”
RangedJS: KubeJS Addon
一个用于制作自定义弓、弩及其他远程武器的 KubeJS 附属模组。
Survivor’s Abilities
为 TFC 添加一些实用属性,方便创建模组和整合包。
评论
登录后评论和评分