API

Événements

Un événement décrit quelque chose qui s’est passé dans le jeu : un joueur s’est connecté, un bloc s’est cassé, quelque chose a subi des dégâts. Il ne décrit pas quel code interne du jeu s’est exécuté : c’est pour ça qu’un mod qui écoute join continue de fonctionner même quand ce code change.

Écouter un événement

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)
            }
        }
    }
}

En CraftScript, les propriétés de l’événement sont disponibles sous forme de variables (player, block…) ou via le nom que tu lui donnes (on break(e)). Tu peux écouter chaque événement depuis autant de fichiers que tu veux : mets chaque règle dans le fichier de son thème.

Tous les événements

Ils se déclenchent tous dans le vrai jeu, côté client ou serveur selon le cas. En CraftScript, tu peux utiliser le nom court ou le nom long en snake_case (join ou player_join).

CraftScript Kotlin Propriétés Annulable
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 Oui
respawn PlayerRespawnEvent player, location
death PlayerDeathEvent player, death_message, keep_inventory
interact PlayerInteractBlockEvent player, block, hand, item Oui
interact_entity PlayerInteractEntityEvent player, entity, hand, item Oui
attack PlayerAttackEvent player, target Oui
key PlayerKeyEvent player, key
use_item PlayerUseItemEvent player, item, hand Oui
command PlayerCommandEvent player, command Oui
break BlockBreakEvent player (peut être null), block, drop_items Oui
place BlockPlaceEvent player (peut être null), block, placed Oui
spawn EntitySpawnEvent entity Oui
damage EntityDamageEvent entity, damage_type, amount (modifiable), attacker Oui
entity_death EntityDeathEvent entity, drops
hit ProjectileHitEvent projectile, shooter, entity or block Oui
ready ModsLoadedEvent mod_ids
plugin_reload PluginReloadEvent plugin_id

Changer ce qui se passe

Certaines propriétés peuvent être modifiées, et le jeu en tient compte :

Événement Propriété Effet
chat message Le joueur dit le nouveau texte.
command command La nouvelle commande s’exécute, au nom de ce joueur.
join, quit join_message, quit_message Annoncé à tout le monde, en plus du message du jeu.
respawn location Le joueur réapparaît à cet endroit.
break drop_items = false Le bloc ne lâche rien.
damage amount Les dégâts subis prennent la nouvelle valeur.
entity_death drops.add(…) Les objets ajoutés tombent là où l’entité est morte, en plus de son butin normal.
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 est un clic droit sur une entité : annulé, il ne se passe rien (ni traite, ni échange, ni monte). attack est un joueur qui frappe une entité : annulé, il n'y a pas de coup. damage donne attacker, celui qui est derrière les dégâts : l'attaquant ou le tireur d'un projectile. key s'exécute quand un joueur appuie sur une touche d'un mod (voir Interface).

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() }
}

Pas encore appliqué. Dans death, modifier death_message ou keep_inventory n’a pas encore d’effet. Crafting le signale une fois dans le journal au lieu de l’ignorer sans rien dire.

Priorité et annulation

Ordre : highest, high, normal, low, lowest et monitor. Quand un écouteur annule l’événement, les suivants ne s’exécutent pas, sauf les écouteurs monitor (et en Kotlin, ceux qui passent ignoreCancelled = true). Un écouteur monitor ne fait qu’observer : il ne doit pas modifier l’événement.

events/falls.craftCraftScript
on damage(e) priority high {
    if e.damage_type == "minecraft:fall" {
        e.amount = e.amount / 2        // des atterrissages plus doux
    }
}
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}")
        }
    }
}

Quand quelque chose échoue

  • Un écouteur qui lève une erreur est consigné avec le nom de son mod, et les autres écouteurs continuent de s’exécuter.
  • /crafting profile (deux fois : démarrer, puis afficher) montre combien de temps chaque mod passe dans ses événements.
  • Un événement que personne n’écoute n’est même pas construit : écouter peu d’événements ne coûte donc rien.