API

Події

Подія описує те, що сталося в грі: гравець зайшов, блок зламано, щось отримало шкоду. Вона не описує, який внутрішній код гри виконався, і саме тому мод, що слухає join, працює й далі, навіть коли цей код змінюється.

Як слухати подію

events/mining.craftCraftScript
import { give_rubies } from "/lib/rewards"
import { SETTINGS } from "/settings"

on break(e) {
    let p = e.player
    if p == null { return }
    if e.block.type == "minecraft:diamond_ore" and chance(SETTINGS["bonus_chance"]) {
        give_rubies(p, 1)
        p.play_sound("rubies:ruby_chime")
        p.world.spawn_particle("rubies:ruby_spark", e.block.location, 12, 0.4, 0.02)
    }
}
events/MiningEvents.ktKotlin
package com.example.rubies.events

object MiningEvents {
    fun register(config: RubiesConfig) {
        Crafting.events.on<BlockBreakEvent> { e ->
            val player = e.player ?: return@on
            if (e.block.type.path == "diamond_ore" && Math.random() < config.dropChance) {
                player.give(ItemStack.of(Items.RUBY))
                player.playSound(Identifier.parse(Sounds.CHIME))
                player.world.spawnParticle(Identifier.parse(Particles.SPARK), e.block.location, count = 12, spread = 0.4, speed = 0.02)
            }
        }
    }
}

У CraftScript властивості події доступні як змінні (player, block…) або через назву, яку ти їй даси (on break(e)). Кожну подію можна слухати зі скількох завгодно файлів: клади кожне правило у файл його теми.

Усі події

Усі вони спрацьовують у справжній грі, на клієнті чи на сервері, як належить. У CraftScript можна використовувати коротку або довгу назву в snake_case (join або player_join).

CraftScript Kotlin Властивості Можна скасувати
server_starting ServerStartingEvent server
start ServerStartedEvent server
stop ServerStoppingEvent server
tick ServerTickEvent server, tick, phase
client_tick ClientTickEvent tick, phase
world_load WorldLoadEvent world
world_unload WorldUnloadEvent world
join PlayerJoinEvent player, join_message
quit, leave PlayerQuitEvent player, quit_message
chat PlayerChatEvent player, message Так
respawn PlayerRespawnEvent player, location
death PlayerDeathEvent player, death_message, keep_inventory
interact PlayerInteractBlockEvent player, block, hand, item Так
interact_entity PlayerInteractEntityEvent player, entity, hand, item Так
attack PlayerAttackEvent player, target Так
key PlayerKeyEvent player, key
use_item PlayerUseItemEvent player, item, hand Так
command PlayerCommandEvent player, command Так
break BlockBreakEvent player (може бути null), block, drop_items Так
place BlockPlaceEvent player (може бути null), block, placed Так
spawn EntitySpawnEvent entity Так
damage EntityDamageEvent entity, damage_type, amount (можна змінювати), attacker Так
entity_death EntityDeathEvent entity, drops
hit ProjectileHitEvent projectile, shooter, entity or block Так
ready ModsLoadedEvent mod_ids
plugin_reload PluginReloadEvent plugin_id

Як змінити те, що відбувається

Деякі властивості можна змінювати, і гра їх дотримується:

Подія Властивість Дія
chat message Гравець каже новий текст.
command command Виконується нова команда від імені цього гравця.
join, quit join_message, quit_message Оголошується всім, на додачу до повідомлення гри.
respawn location Гравець відроджується там.
break drop_items = false З блока нічого не випадає.
damage amount Отримана шкода дорівнює новому значенню.
entity_death drops.add(…) Додані предмети випадають там, де загинула істота, на додачу до звичайної здобичі.
events/hunting.craftCraftScript
on entity_death(e) {
    if e.entity.type == "minecraft:zombie" and chance(0.05) {
        e.drops.add(item("rubies:ruby", 1))
    }
}

interact_entity — клік правою кнопкою по сутності: якщо скасувати, нічого не станеться (ні доїння, ні торгівлі, ні їзди). attack — гравець б'є сутність: якщо скасувати, удару немає. damage дає attacker — того, хто стоїть за уроном: нападника або стрільця, що випустив снаряд. key спрацьовує, коли гравець натискає клавішу мода (див. Інтерфейс).

events/entities.craftCraftScript
on interact_entity(e) {
    if e.entity.type == "minecraft:cow" { e.player.send("This cow won't be milked"); e.cancel() }
}

on attack(e) {
    if e.target.type == "minecraft:pig" { e.player.action_bar("This pig is protected"); e.cancel() }
}

Ще не застосовується. У death зміна death_message або keep_inventory поки що не діє. Crafting один раз попереджає про це в журналі, а не ігнорує мовчки.

Пріоритет і скасування

Порядок: highest, high, normal, low, lowest і monitor. Коли слухач скасовує подію, наступні не виконуються, окрім слухачів monitor (і в Kotlin тих, що передають ignoreCancelled = true). Слухач monitor лише спостерігає: він не має змінювати подію.

events/falls.craftCraftScript
on damage(e) priority high {
    if e.damage_type == "minecraft:fall" {
        e.amount = e.amount / 2        // м’якші приземлення
    }
}
events/ChatEvents.ktKotlin
object ChatEvents {
    fun register() {
        Crafting.events.on<PlayerChatEvent>(EventPriority.HIGHEST) { e ->
            if (e.message.startsWith("!")) e.cancel()
        }
        Crafting.events.on<PlayerChatEvent>(EventPriority.MONITOR) { e ->
            if (!e.isCancelled) Crafting.runtime.logger("chat").info("${e.player.name}: ${e.message}")
        }
    }
}

Коли щось не працює

  • Слухач, що викидає помилку, записується в журнал із назвою свого мода, а інші слухачі працюють далі.
  • /crafting profile (двічі: почати, потім переглянути) показує, скільки часу кожен мод витрачає на свої події.
  • Подія, яку ніхто не слухає, навіть не створюється, тож слухати кілька подій нічого не коштує.