跳到主要内容

脚本预设

本文给出一些常用的脚本预设,供开发者使用。

温馨提示
  1. 本文假设读者已对脚本运行有了基本的了解。如果还没有了解,请在对应的文档或教程中先行学习。

  2. 本文默认采用以下文件。您可按需在您指定的文件中采用本文的参考代码。

    • BP_npc 文件图标BP_npc:行为包根目录
      • scripts 文件图标scripts:脚本
        • main.js 文件图标main.js:国际版脚本入口文件(新增或更改)
        • modMain.py 文件图标modMain.py:中国版脚本入口文件(新增或更改)
        • templateServerMain.py 文件图标templateServerMain.py:中国版服务端脚本(新增或更改)
        • templateClientMain.py 文件图标templateClientMain.py:中国版服务端脚本(新增或更改)
      • manifest.json 文件图标manifest.json:清单文件(更改)
    中国版脚本的初始配置

    注意高亮行的template应填写为您的项目的命名空间备注:下面的初始配置比较偏向国际版脚本编程习惯

    modMain.py
    # -*- coding: utf-8 -*-
    from mod.common.mod import Mod
    import mod.server.extraServerApi as serverApi
    import mod.client.extraClientApi as clientApi

    @Mod.Binding(name = "template", version = "1.0.0")
    class templateSystem(object):
    def __init__(self):
    pass

    @Mod.InitServer()
    def serverSubscribe(self):
    serverApi.RegisterSystem("templateSystem", "templateServer", "scripts.templateServerMain.templateServer")

    @Mod.DestroyServer()
    def serverUnsubscribe(self):
    pass

    @Mod.InitClient()
    def clientSubscribe(self):
    clientApi.RegisterSystem("templateSystem", "templateClient", "scripts.templateClientMain.templateClient")

    @Mod.DestroyClient()
    def clientUnsubscribe(self):
    pass

    templateServerMain.py
    # -*- coding: utf-8 -*-
    import mod.server.extraServerApi as serverApi
    import math

    ServerSystem = serverApi.GetServerSystemCls()
    compFactory = serverApi.GetEngineCompFactory()
    defaultNamespace = serverApi.GetEngineNamespace()
    defaultSystemName = serverApi.GetEngineSystemName()
    levelId = serverApi.GetLevelId()

    class templateServer(ServerSystem):

    def __init__(self, namespace, systemName):
    super(templateServer, self).__init__(namespace, systemName)
    self.subscribe()

    def subscribe(self):
    pass

    def unsubscribe(self):
    pass

    templateClientMain.py
    # -*- coding: utf-8 -*-
    import mod.client.extraClientApi as clientApi
    ClientSystem = clientApi.GetClientSystemCls()

    class templateClient(ClientSystem):

    def __init__(self, namespace, systemName):
    super(templateClient, self).__init__(namespace, systemName)
    self.subscribe()

    def subscribe(self):
    pass

    def unsubscribe(self):
    pass


血量监控

用于检查实体的血量,并打印到health记分板上。

国际版

参考事件EntityHealthChangedAfterEvent

如果您需要,您可以扩展entityTypes中所指定的实体类型,以使这段代码对更多类型的实体生效。

main.js
import { Entity, EntityHealthComponent, world } from "@minecraft/server";

// ===== 实体血量监控 =====

world.afterEvents.entitySpawn.subscribe( event => {
/** 刚生成的实体 */
const entity = event.entity;
/** 该实体的血量组件 @type {EntityHealthComponent} */
const entityHealth = entity.getComponent("minecraft:health");
/** 该实体的血量最大值 */
const entityMaxHealth = entityHealth?.effectiveMax;

// 此处是为了防止某些实体无血量而导致报错
if ( entityMaxHealth !== undefined ) {
printHealth(entity, entityMaxHealth);
}
})

world.afterEvents.entityHealthChanged.subscribe(event => {
printHealth(event.entity, event.newValue);
});

/**
* @param {Entity} entity
* @param {number} healthValue
*/
function printHealth( entity, healthValue ) {
/** 要检查的实体 */
const entityTypes = [ "minecraft:player", "minecraft:sheep" ];

// 若实体在允许的实体列表中,则打印实体血量到health记分板上
if ( entityTypes.includes(entity.typeId) ) {
/** 实体血量更改后的血量(整数型) */
const healthValueInt = Math.ceil(healthValue);
entity.runCommand(`scoreboard players set @s health ${healthValueInt}`);
}
}

中国版

服务端脚本。参考事件HealthChangeServerEventAddEntityServerEvent

如果您需要,您可以扩展entityTypes中所指定的实体类型,以使这段代码对更多类型的实体生效。

templateServerMain.py(服务端脚本)
class templateServer(ServerSystem):

def subscribe(self):
self.ListenForEvent(defaultNamespace, defaultSystemName, "AddEntityServerEvent", self, self.entitySpawn)
self.ListenForEvent(defaultNamespace, defaultSystemName, "HealthChangeServerEvent", self, self.entityHealthChanged)

# ===== 实体血量监控 =====

def entitySpawn(self, event):
# type: ( dict ) -> None

entityId = event["id"] # 刚生成的实体 ID
entityMaxHealth = compFactory.CreateAttr(entityId).GetAttrMaxValue(0) # 刚生成的实体的血量最大值

# 此处是为了防止某些实体无血量而导致报错
if entityMaxHealth != None:
self.printHealth(entityId, entityMaxHealth)

def entityHealthChanged(self, event):
# type: ( dict ) -> None
self.printHealth(event["entityId"], event["to"])

def printHealth(self, entityId, healthValue):
# type: ( str, float ) -> None

entityTypeId = compFactory.CreateEngineType(entityId).GetEngineTypeStr() # 实体的类型 ID
entityTypes = ["minecraft:player", "minecraft:sheep"] # 要检查的实体

# 若实体在允许的实体列表中,则打印实体血量到health记分板上
if entityTypeId in entityTypes:
healthValueInt = int(math.ceil(healthValue)) # 实体血量更改后的血量(整数型)
compFactory.CreateCommand(levelId).SetCommand("/scoreboard players set @s health {}".format(healthValueInt), entityId)

使用物品

用于检查玩家是否右键(长按)使用物品,并执行函数items/(物品ID)

注意:物品为开始使用时触发。因此,通常用于一些不能蓄力甚至使用后无明显效果的物品,例如木棍。

国际版

参考事件ItemUseAfterEvent

如果您需要,您可以扩展usableItems中所指定的物品 ID,以使这段代码对更多类型的物品生效。

main.js
import { world } from "@minecraft/server";

// ===== 使用物品 =====

world.afterEvents.itemUse.subscribe(event => {
const usableItems = [ "minecraft:stick" ];
if (usableItems.includes(event.itemStack.typeId)) {
event.source.runCommand(`function items/${event.itemStack.typeId.split(":")[1]}`);
}
});

中国版

服务端脚本。参考事件ItemUseAfterServerEvent

如果您需要,您可以扩展usableItems中所指定的物品 ID,以使这段代码对更多类型的物品生效。

templateServerMain.py(服务端脚本)
class templateServer(ServerSystem):

def subscribe(self):
self.ListenForEvent(defaultNamespace, defaultSystemName, "ItemUseAfterServerEvent", self, self.itemUse)

# ===== 使用物品 =====

def itemUse(self, event):
# type: ( dict ) -> None
sourceId = event["entityId"]
itemStack = event["itemDict"]
usableItems = []
if itemStack["newItemName"] in usableItems:
compFactory.CreateCommand(levelId).SetCommand("/function items/{}".format(itemStack["newItemName"].split(":")[1]), sourceId)

使用完毕物品

用于检查玩家是否右键(长按)使用物品,并执行函数items/(物品ID)

注意:物品为使用完毕时触发。因此,通常用于一些可蓄力使用的物品,例如弓、药水、食物等。

国际版

参考事件ItemCompleteUseAfterEvent

如果您需要,您可以扩展usableItems中所指定的物品 ID,以使这段代码对更多类型的物品生效。

main.js
import { world } from "@minecraft/server";

// ===== 使用完毕物品 =====

world.afterEvents.itemCompleteUse.subscribe(event => {
const usableItems = [ "minecraft:potion" ];
if (usableItems.includes(event.itemStack.typeId)) {
event.source.runCommand(`function items/${event.itemStack.typeId.split(":")[1]}`);
}
});
中国版

服务端脚本。参考事件ActorUseItemServerEvent

如果您需要,您可以扩展usableItems中所指定的物品 ID,以使这段代码对更多类型的物品生效。

templateServerMain.py(服务端脚本)
class templateServer(ServerSystem):

def subscribe(self):
self.ListenForEvent(defaultNamespace, defaultSystemName, "ActorUseItemServerEvent", self, self.itemCompleteUse)

# ===== 使用完毕物品 =====

def itemCompleteUse(self, event):
# type: ( dict ) -> None
sourceId = event["playerId"]
itemStack = event["itemDict"]
usableItems = []
if itemStack["newItemName"] in usableItems:
compFactory.CreateCommand(levelId).SetCommand("/function items/{}".format(itemStack["newItemName"].split(":")[1]), sourceId)