Перейти к основному содержимому

API для разработчиков

Сгенерированный справочник Java содержит классы, методы и сигнатуры с возможностью поиска, а также версию исходного кода и коммит каждого модуля.

Требования​

BetterStructures требует:

  • Java 21 или выше
  • Сервер Spigot/Paper
  • Плагин WorldEdit (жёсткая зависимость)

Необязательные зависимости:

  • WorldGuard — для функций защиты регионов (для полной интеграции также требуется установка EliteMobs)
  • EliteMobs — для интеграции спавна элитных мобов
  • MythicMobs — для интеграции с MythicMobs
  • Terralith, Iris, Terra, TerraformGenerator — для совместимости с пользовательскими биомами

Публичный репозиторий

Maven​

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

<dependency>
<groupId>com.magmaguy</groupId>
<artifactId>BetterStructures</artifactId>
<version>2.7.7</version>
<scope>provided</scope>
</dependency>

Доступные версии перечислены в репозитории Maven. Пример использует опубликованную версию 2.7.7; текущий исходный код имеет версию 2.7.7. Выбирайте версию, соответствующую установленному плагину.

Gradle

repositories {
maven {
name = "magmaguyRepoReleases"
url = uri("https://repo.magmaguy.com/releases")
}
}

dependencies {
compileOnly("com.magmaguy:BetterStructures:2.7.7")
}

Доступные версии перечислены в репозитории Maven. Пример использует опубликованную версию 2.7.7; текущий исходный код имеет версию 2.7.7. Выбирайте версию, соответствующую установленному плагину.

События

Примечание: события находятся в com.magmaguy.betterstructures.api

Импорты пакетов​

import com.magmaguy.betterstructures.api.BuildCustomMarkerEvent;
import com.magmaguy.betterstructures.api.BuildPasteCompleteEvent;
import com.magmaguy.betterstructures.api.BuildPlaceEvent;
import com.magmaguy.betterstructures.api.ChestFillEvent;
import com.magmaguy.betterstructures.api.WorldGenerationFinishEvent;
import com.magmaguy.betterstructures.buildingfitter.FitAnything;
import com.magmaguy.betterstructures.modules.ModularWorld;
import com.magmaguy.betterstructures.thirdparty.WorldGuard;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Container;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.List;

BuildPlaceEvent​

Вызывается, когда постройка должна быть размещена. Предоставляет данные о том, какая постройка будет размещена и где, а также другую информацию через объект FitAnything.

Не пытайтесь изменять размещаемую постройку! Вы можете изменить мелкие детали, но замена всей постройки, скорее всего, приведёт к плохому соответствию.

Событие можно отменить.

ChestFillEvent​

Вызывается, когда сундук заполняется. Использует снимок инвентаря контейнера для безопасного сохранения данных, которые будут применены.

Вы можете изменять добычу с помощью методов Inventory addItem() или removeItem(), применённых к снимку инвентаря контейнера, полученному через getContainer().getSnapshotInventory().

Также можно вызвать getTreasureConfigFilename(), чтобы определить, какая конфигурация таблицы добычи использовалась для заполнения этого сундука.

Событие можно отменить.

BuildCustomMarkerEvent​

Вызывается по одному разу для каждой таблички [custom] после вставки блоков, добычи, мобов и сущностей структуры. BetterStructures сначала удаляет табличку, поэтому в getLocation() находится воздух, и вы можете поставить туда что угодно.

  • getId() — строки 2-4 таблички, соединённые без разделителей, например Zombie_Plus
  • getLines() — строки 2-4 по отдельности, без пробелов по краям; пустые строки возвращаются как пустые строки
  • getLocation() — местоположение таблички в мире
  • getFitAnything() — вставляемая структура, как в BuildPlaceEvent

Это событие НЕ может быть отменено.

BuildPasteCompleteEvent​

Вызывается, когда обычная структура полностью вставлена, после всех BuildCustomMarkerEvent для неё. Вставка растягивается на несколько тиков, поэтому именно здесь надёжнее всего работать с размещённой структурой. BuildPlaceEvent срабатывает до того, как что-либо из этого произойдёт. Если какой-то шаг завершения не удаётся, например босс с таблички не может появиться, вставка останавливается и это событие не вызывается.

  • getFitAnything() — вставленная структура
  • getLowestCorner() и getHighestCorner() — угловые блоки вставленной схематики в мировых координатах, оба включительно
  • getBoundingBox() — пространство, занятое этими блоками
  • getContainerLocations() — все сундуки, сундуки-ловушки, шалкеровые ящики и бочки из схематики, независимо от того, заполнил ли их BetterStructures добычей

Это событие НЕ может быть отменено.

WorldGenerationFinishEvent​

Вызывается, когда модульное подземелье, сгенерированное в собственном мире (isWorldGeneration: true), завершает вставку. Подземелья, вставленные в существующие миры, его не вызывают. Предоставляет доступ к объекту ModularWorld, содержащему все данные о сгенерированном мире, включая точки спавна, расположение сундуков и точки выхода.

Это событие НЕ может быть отменено.

Вы можете получить доступ к данным мира через метод getModularWorld(). См. раздел ModularWorld ниже для списка всех доступных методов.

Пример обработчика событий

public class MyBetterStructuresListener implements Listener {

@EventHandler
public void onBuildPlace(BuildPlaceEvent event) {
FitAnything build = event.getFitAnything();
Location location = build.getLocation();
// Custom logic here
// event.setCancelled(true); // To prevent placement
}

@EventHandler
public void onChestFill(ChestFillEvent event) {
Container container = event.getContainer();
Inventory inv = container.getSnapshotInventory();
// Modify inventory here
inv.addItem(new ItemStack(Material.DIAMOND, 1));
}

@EventHandler
public void onCustomMarker(BuildCustomMarkerEvent event) {
if (!event.getId().equals("Zombie_Plus")) return;
// Spawn your own mob at the marker
event.getLocation().getWorld().spawnEntity(event.getLocation().add(0.5, 0, 0.5), EntityType.ZOMBIE);
}

@EventHandler
public void onPasteComplete(BuildPasteCompleteEvent event) {
for (Location containerLocation : event.getContainerLocations()) {
if (!(containerLocation.getBlock().getState() instanceof Container container)) continue;
// Replace the contents with your own loot
container.getInventory().clear();
container.getInventory().addItem(new ItemStack(Material.EMERALD, 3));
}
}

@EventHandler
public void onWorldGenFinish(WorldGenerationFinishEvent event) {
ModularWorld world = event.getModularWorld();
// Access generated world data
List<Location> spawns = world.getSpawnLocations();
}
}

Ключевые классы

FitAnything​

Класс FitAnything создаётся при вставке постройки и обрабатывает все аспекты вставки, включая заполнение сундуков и спавн мобов.

Доступные методы-геттеры:

  • getSchematicContainer() — возвращает контейнер схематики
  • getSchematicClipboard() — возвращает объект Clipboard из WorldEdit
  • getSchematicOffset() — возвращает вектор смещения для размещения
  • getLocation() — возвращает Location размещения

Эти методы полезны при создании пользовательских защит регионов или анализе размещения построек.

ModularWorld​

Класс ModularWorld представляет сгенерированный модульный мир и предоставляется через WorldGenerationFinishEvent. Он содержит все данные о расположениях и методы для спавна сущностей и контейнеров в сгенерированном мире.

Ключевые методы:

  • getWorld() — возвращает экземпляр Bukkit World
  • getWorldFolder() — возвращает File папки мира
  • getCenter() — возвращает начальную точку подземелья, от которой отсчитываются зоны сложности
  • getHorizontalSize() — возвращает ширину подземелья в блоках, (2 × radius − 1) × moduleSizeXZ
  • getDifficultyId(Location) — возвращает ID сложности инстанса EliteMobs для местоположения: 2 в пределах шестой части ширины от центра (по большему из смещений по X и Z), 1 в пределах трети, иначе 0
  • getSpawnLocations() — возвращает все отмеченные точки спавна (List<Location>)
  • getChestLocations() — возвращает все точки спавна сундуков (List<Location>)
  • getBarrelLocations() — возвращает все точки спавна бочек (List<Location>)
  • getExitLocations() — возвращает все точки выхода. Учтите, что ExitLocation — приватная вложенная запись (record), поэтому извне плагина результат можно хранить только как список с wildcard; публичного типа для его элементов сейчас нет.
  • spawnChests() — спавнит сундуки в отмеченных местах, возвращает List<Block>
  • spawnBarrels() — спавнит бочки в отмеченных местах, возвращает List<Block>
  • spawnInaccessibleExitLocations() — спавнит верхние схематики лифтов, возвращает List<Location>
  • spawnAccessibleExitLocations() — спавнит нижние схематики лифтов, возвращает List<Location>
  • spawnOtherEntities() — на следующем тике обрабатывает таблички пулов спавна, которые вставка ещё не обработала, а затем снова вызывает WorldGenerationFinishEvent. Обычно вставка сама обрабатывает все таблички пулов. Вызов этого метода из обработчика WorldGenerationFinishEvent заставляет его повторяться каждый тик.
  • spawnInstancedEntities() — спавнит инстансных боссов из пулов спавна, стоящих в очереди, с уровнем maxLevel их пула и ID сложности из getDifficultyId, и возвращает List<InstancedBossEntity>. Каждый босс хранит имя файла пула спавна как пользовательские данные под ключом betterstructures:spawnpool.

WorldGuard​

Класс WorldGuard обрабатывает защиту регионов WorldGuard. Утилитарный метод public static ProtectedRegion generateProtectedRegion(FitAnything fitAnything, String regionName) предоставляется разработчикам для удобного подключения собственной схемы защиты регионов поверх BetterStructures.

Другие полезные методы:

  • checkArea(Location, Player) — проверяет, находится ли локация в защищённом регионе BetterStructures (возвращает true, если регион защищён, и отправляет игроку предупреждающее сообщение)
  • Protect(...) — создаёт защищённые регионы программно
  • Unprotect(CustomBossEntity) — снимает защиту региона, когда босс убит