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_PlusgetLines()— строки 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 из WorldEditgetSchematicOffset()— возвращает вектор смещения для размещенияgetLocation()— возвращает Location размещения
Эти методы полезны при создании пользовательских защит регионов или анализе размещения построек.
ModularWorld
Класс ModularWorld представляет сгенерированный модульный мир и предоставляется через WorldGenerationFinishEvent. Он содержит все данные о расположениях и методы для спавна сущностей и контейнеров в сгенерированном мире.
Ключевые методы:
getWorld()— возвращает экземпляр Bukkit WorldgetWorldFolder()— возвращает File папки мираgetCenter()— возвращает начальную точку подземелья, от которой отсчитываются зоны сложностиgetHorizontalSize()— возвращает ширину подземелья в блоках,(2 × radius − 1) × moduleSizeXZgetDifficultyId(Location)— возвращает ID сложности инстанса EliteMobs для местоположения:2в пределах шестой части ширины от центра (по большему из смещений по X и Z),1в пределах трети, иначе0getSpawnLocations()— возвращает все отмеченные точки спавна (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)— снимает защиту региона, когда босс убит