Zum Hauptinhalt springen

FreeMinecraftModels API und Entwicklerhandbuch

FreeMinecraftModels ist sowohl ein eigenständiges Plugin als auch eine API-Oberfläche für andere Plugins.

Maven Repository

<repository>
<id>magmaguy-repo-releases</id>
<name>MagmaGuy's Repository</name>
<url>https://repo.magmaguy.com/releases</url>
</repository>
<repository>
<id>magmaguy-repo-snapshots</id>
<name>MagmaGuy's Snapshot Repository</name>
<url>https://repo.magmaguy.com/snapshots</url>
</repository>

Abhängigkeit

<dependency>
<groupId>com.magmaguy</groupId>
<artifactId>FreeMinecraftModels</artifactId>
<version>LATEST.VERSION.HERE</version>
<scope>provided</scope>
</dependency>

Verwende es als compileOnly/provided. Shade das Plugin nicht in deine eigene Jar.

Kern-Einstiegspunkte

  • ModeledEntityManager.modelExists(String)
  • ModeledEntityManager.reload()
  • ModeledEntityManager.getAllEntities()
  • ModeledEntityManager.getDynamicEntities()
  • ModeledEntityManager.propEntities()

Kern-Laufzeittypen

  • ModeledEntity
  • StaticEntity
  • DynamicEntity
  • PropEntity

Entities erstellen

StaticEntity preview = StaticEntity.create("example_model", location);
DynamicEntity mobModel = DynamicEntity.create("example_model", livingEntity);
DynamicEntity mount = DynamicEntity.createWithInvisibility("example_model", livingEntity);
PropEntity prop = PropEntity.spawnPropEntity("example_model", location);

Alle Erstellungspfade geben null zurück, wenn die angeforderte Modell-ID nicht geladen ist.

createWithInvisibility ist eine Variante, die einen Unsichtbarkeitstrank anwendet, anstatt die Entity vor Clients zu verbergen. Dies hält die Entity clientseitig getrackt, was für die Fahrzeugsteuerung benötigt wird (intern von /fmm mount verwendet).

Nützliche Laufzeitmethoden

  • ModeledEntity#setDisplayName(String)
  • ModeledEntity#setDisplayNameVisible(boolean)
  • ModeledEntity#setLeftClickCallback(...)
  • ModeledEntity#setRightClickCallback(...)
  • ModeledEntity#setHitboxContactCallback(...)
  • ModeledEntity#setModeledEntityHitByProjectileCallback(...)
  • ModeledEntity#playAnimation(String, boolean, boolean)
  • ModeledEntity#stopCurrentAnimations()
  • ModeledEntity#hasAnimation(String)
  • DynamicEntity#setSyncMovement(boolean)
  • Bone#getBoneLocation()

Event-Oberfläche

Generische Interaktions-Events:

  • ModeledEntityLeftClickEvent
  • ModeledEntityRightClickEvent
  • ModeledEntityHitboxContactEvent
  • ModeledEntityHitByProjectileEvent

Typisierte Varianten existieren auch für StaticEntity, DynamicEntity und PropEntity.

ModeledEntityHitByProjectileEvent und OBB-Projektilerkennung

FMM verwendet OBB (orientierte Begrenzungsbox) Treffererkennung für Projektile gegen modellierte Entities. Wenn ein Projektil die OBB-Hitbox einer modellierten Entity schneidet, löst FMM ein ModeledEntityHitByProjectileEvent aus. Dies ist ein standardmäßig abbrechbares Bukkit-Event.

Wichtige Details:

  • Pfeilschaden wird mit Unterstützung des POWER-Verzauberungsbonus berechnet
  • Die PIERCING-Verzauberung wird respektiert -- Pfeile können durch zu zusätzlichen Zielen durchdringen
  • Breche das Event ab, um Schaden zu verhindern und den Treffer vollständig zu blockieren
@EventHandler
public void onProjectileHitModel(ModeledEntityHitByProjectileEvent event) {
ModeledEntity target = event.getModeledEntity();
Projectile projectile = event.getProjectile();
// Abbrechen um Schaden zu verhindern
event.setCancelled(true);
}

Item- und Modell-Hilfsprogramme

ModelItemFactory

Factory-Klasse zum programmatischen Erstellen von modellbezogenen ItemStacks.

// Erstelle ein Prop-Platzierungsitem (verwendet "model_id" PDC-Schlüssel)
ItemStack placementItem = ModelItemFactory.createModelItem("lamp_post", Material.STICK);

// Erstelle ein benutzerdefiniertes Item aus der Konfiguration (verwendet "fmm_item_id" PDC-Schlüssel)
PropScriptConfigFields config = ItemScriptManager.getItemDefinitions().get("magic_sword");
ItemStack customItem = ModelItemFactory.createCustomItem("magic_sword", config);
  • createModelItem(String modelId, Material material) -- erstellt ein Platzierungsitem für Props. Auf 1.21.4+ wird automatisch Display-Model-Rendering angewendet, wenn ein Display-JSON existiert.
  • createCustomItem(String itemId, PropScriptConfigFields config) -- erstellt ein benutzerdefiniertes Item mit Name, Lore, Verzauberungen und Display-Model aus der einheitlichen Konfiguration.
  • formatModelName(String modelId) -- Hilfsfunktion, die eine Modell-ID wie 01_em_flame_sword in Flame Sword konvertiert.

DisplayModelRegistry

Einfache Registry, die verfolgt, welche Modelle ein Display-JSON verfügbar haben.

// Prüfe ob ein Modell ein Display-Model-JSON registriert hat
boolean has3D = DisplayModelRegistry.hasDisplayModel("magic_sword");
  • register(String modelId) -- registriert eine Modell-ID (wird intern beim Reload aufgerufen)
  • hasDisplayModel(String modelId) -- gibt true zurück, wenn ein .json-Display-Model für dieses Modell existiert
  • shutdown() -- löscht alle Registrierungen

ItemScriptManager

Verwaltet den Lebenszyklus von Lua-Skripten pro Spieler für benutzerdefinierte Items (Modelle mit material: in ihrer YML-Konfiguration gesetzt).

// Alle registrierten benutzerdefinierten Item-Definitionen abrufen
Map<String, PropScriptConfigFields> items = ItemScriptManager.getItemDefinitions();

// Die aktive Lua-Skriptinstanz für einen Spieler + Item abrufen
ScriptInstance instance = ItemScriptManager.getActiveScript(playerUUID, "magic_sword");

// Alle aktiven Skripte für einen Spieler abrufen
Map<String, ScriptInstance> scripts = ItemScriptManager.getActiveScripts(playerUUID);
  • scanForCustomItems(File modelsFolder) -- scannt Modell-YML-Konfigurationen nach benutzerdefinierten Items
  • updateEquippedScripts(Player player) -- vergleicht ausgerüstete Items mit laufenden Skripten, löst Ausrüsten/Ablegen-Hooks aus
  • removePlayer(Player player) -- fährt alle Skripte für einen Spieler herunter (beim Verlassen aufrufen)
  • getItemDefinitions() -- gibt die Map von Item-ID zu PropScriptConfigFields zurück

ScriptedItemAPI

Öffentliche API für externe Plugins zur Integration mit FMMs geskriptetem Item-System. Dies ermöglicht es anderen Plugins, ihre eigenen ItemStacks mit FMMs geskripteten Item-Daten zu versehen (PDC-Tag + Item-Modell), damit FMMs Lua-Skript-Hooks für diese Items feuern, ohne dass FMM den Namen, die Lore oder die Verzauberungen des Items überschreibt.

// Prüfe ob eine geskriptete Item-Definition existiert
boolean exists = ScriptedItemAPI.isValidItemId("flame_blade");

// FMM geskriptete Item-Daten auf einen bestehenden ItemStack anwenden
// Dies setzt:
// - Den fmm_item_id PDC-Tag (damit FMMs Skript-System das Item erkennt)
// - Das Item-Modell (1.21.4+) aus FMMs Display-Model-Registry
// Ändert NICHT Name, Lore, Verzauberungen oder andere Item-Eigenschaften.
boolean success = ScriptedItemAPI.applyScriptedItemData(itemStack, "flame_blade");

// Die Konfiguration für ein geskriptetes Item abrufen
PropScriptConfigFields config = ScriptedItemAPI.getItemConfig("flame_blade");
  • isValidItemId(String itemId) -- gibt true zurück, wenn die Item-ID in FMMs Item-Definitionen registriert ist
  • applyScriptedItemData(ItemStack itemStack, String itemId) -- versieht einen bestehenden ItemStack mit PDC-Tag und Item-Modell. Gibt true bei Erfolg zurück, false wenn die Item-ID ungültig ist oder der ItemStack keine Meta hat. Bogen/Armbrust-Hinweis: wenn die gegebene itemId kein Display-Model hat, aber itemId + "_idle" eines hat (d.h. das Item hat Bogen/Armbrust-Zustandsmodelle), verwendet die Methode automatisch das _idle-Modell als Display-Model
  • getItemConfig(String itemId) -- gibt die PropScriptConfigFields für die gegebene Item-ID zurück, oder null wenn nicht gefunden
EliteMobs-Integration

EliteMobs verwendet diese API intern über das scriptedItem-Konfigurationsfeld. Wenn ein benutzerdefiniertes EliteMobs-Item scriptedItem: flame_blade setzt, baut EliteMobs sein Item normal auf (Name, Lore, Verzauberungen, Level) und ruft dann ScriptedItemAPI.applyScriptedItemData() auf, um FMMs Modell- und Skriptverhalten obendrauf hinzuzufügen.

PropScriptConfigFields

Einheitliche Konfigurationsklasse für Modell-YML-Konfigurationsdateien. Wird sowohl von Prop-Skripten als auch von benutzerdefinierten Items verwendet.

# Beispiel: torch_01.yml
isEnabled: true
scripts:
- torch_glow.lua
material: STICK # Wenn gesetzt, wird das Modell ein benutzerdefiniertes Item
name: "&eMagic Torch" # Benutzerdefinierter Anzeigename (optional)
lore: # Benutzerdefinierte Lore-Zeilen (optional)
- "&7Glows in the dark"
enchantments: # Verzauberungen (optional, Format: NAME,LEVEL)
- "FIRE_ASPECT,1"

Schlüsselmethoden: isCustomItem(), getParsedMaterial(), getParsedEnchantments(), getScripts().

Lua-Skripting

FreeMinecraftModels unterstützt Lua-Skripte sowohl für Props als auch für benutzerdefinierte Items über die MagmaCore 2.0 Skript-Engine. Skriptdateien werden in plugins/FreeMinecraftModels/scripts/ platziert und über eine begleitende YML-Konfiguration neben der Modelldatei an Modelle gebunden.

Prop-Skript-Hooks

HookAuslöser
on_spawnProp wird in die Welt gespawnt
on_game_tickJeden Tick, solange der Prop existiert
on_zone_enterEin Spieler betritt die Zone des Props
on_zone_leaveEin Spieler verlässt die Zone des Props
on_destroyProp wird entfernt
on_left_clickSpieler klickt den Prop mit Links
on_right_clickSpieler klickt den Prop mit Rechts
on_projectile_hitEin Projektil trifft den Prop

Item-Skript-Hooks

Benutzerdefinierte Items (Modelle mit gesetztem material:) unterstützen 22 Lua-Hooks:

HookAuslöser
on_equipItem wird in einen überwachten Ausrüstungsslot gelegt
on_unequipItem verlässt einen überwachten Ausrüstungsslot
on_game_tickJeden Tick, solange das Item ausgerüstet ist
on_attack_entitySpieler greift eine Entity an, während er das Item hält
on_kill_entitySpieler tötet eine Entity, während er das Item hält
on_take_damageSpieler nimmt Schaden, während das Item ausgerüstet ist
on_shield_blockSpieler blockt mit einem Schild
on_shoot_bowSpieler schießt einen Bogen
on_projectile_hitEin vom Spieler abgefeuertes Projektil trifft etwas
on_projectile_launchSpieler wirft ein Projektil
on_right_clickSpieler macht Rechtsklick mit dem Item
on_left_clickSpieler macht Linksklick mit dem Item
on_shift_right_clickSpieler macht Shift+Rechtsklick mit dem Item
on_shift_left_clickSpieler macht Shift+Linksklick mit dem Item
on_interact_entitySpieler klickt rechts auf eine Entity mit dem Item
on_swap_handsSpieler tauscht das Item zwischen den Händen
on_dropSpieler lässt das Item fallen
on_break_blockSpieler baut einen Block ab, während er das Item hält
on_consumeSpieler konsumiert das Item
on_item_damageItem nimmt Haltbarkeitsschaden
on_fishSpieler benutzt eine Angel
on_deathSpieler stirbt, während das Item ausgerüstet ist

Item-Skripte erhalten context.item (mit der Item-ID und Spielerinformationen) anstelle von context.prop.

Prop-Skript-Context-Tabelle

Skripte erhalten eine context-Tabelle. Hier ist eine Zusammenfassung der wichtigsten APIs -- siehe Lua Prop- und Item-API für vollständige Details.

context.prop:

  • model_id -- der Modellname der Vorlage
  • current_location -- die aktuelle Position des Props
  • play_animation(name, blend, loop) -- spielt die benannte Animation ab (blend und loop sind standardmäßig true)
  • stop_animation() -- stoppt alle aktuellen Animationen
  • hurt_visual() -- spielt die Verletzungsanimation (roter Blitz) auf dem Prop ab
  • pickup() -- entfernt den Prop und droppt sein Platzierungs-Item
  • mount(player) -- lässt einen Spieler auf dem Prop reiten
  • dismount(player) -- entfernt einen Spieler vom Prop
  • get_passengers() -- gibt eine Liste der Spieler zurück, die derzeit auf dem Prop reiten
  • spawn_elitemobs_boss(filename, x, y, z) -- spawnt einen EliteMobs-Boss relativ zum Prop

context.event:

  • Verfügbar in on_left_click, on_right_click und on_projectile_hit
  • cancel(), uncancel(), is_cancelled
  • player -- der Spieler, der das Event ausgelöst hat

context.world:

  • spawn_entity(entity_type, location) -- spawnt eine Vanilla-Entity
  • set_block_at(location, material) -- setzt einen Block in der Welt
  • Plus Partikel, Sounds, Block-Abfragen, Blitze und Suche nach nahegelegenen Entities

Spieler-Objekte (von context.event.player):

  • get_held_item() -- gibt das Item zurück, das der Spieler hält
  • consume_held_item() -- entfernt eines des gehaltenen Items
  • has_item(material) -- prüft, ob der Spieler ein Item hat
  • send_message(text) -- sendet eine Chat-Nachricht an den Spieler
  • game_mode -- der aktuelle Spielmodus des Spielers

Prop-Skript-Beispiel

function on_spawn(context)
context.prop.play_animation("idle", true, true)
end

function on_right_click(context)
context.prop.play_animation("activate", false, false)
end

Item-Skript-Beispiel

function on_equip(context)
context.event.player.send_message("&6You equipped the Flame Blade!")
end

function on_attack_entity(context)
-- Fire effect on hit
context.event.player.send_message("&cBurn!")
end

function on_unequip(context)
context.event.player.send_message("&7Flame Blade sheathed.")
end

Hinweise

  • FreeMinecraftModels ist eine installierte Plugin-Abhängigkeit, keine einbettbare Bibliothek.
  • Wenn dein Plugin frisch importierte Modelle benötigt, rufe ModeledEntityManager.reload() auf, anstatt zu versuchen, den FreeMinecraftModels-Zustand selbst neu aufzubauen.
  • Alle Plugins im Nightbreak-Ökosystem hängen jetzt von MagmaCore 2.0.0-SNAPSHOT ab, das die gemeinsame Lua-Skript-Engine enthält, die von FreeMinecraftModels-Prop-Skripten und EliteMobs-Lua-Powers verwendet wird.