LoParkour/src/main/java/dev/loki/loparkour/generator/Island.java
2026-03-10 12:39:21 +01:00

108 lines
3.8 KiB
Java

package dev.loki.loparkour.generator;
import java.util.ArrayList;
import dev.loki.loparkour.LoParkour;
import dev.loki.loparkour.config.Config;
import dev.loki.loparkour.session.Session;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.NoSuchElementException;
/**
* Spawn island handler.
*
* @author loki
* @since 5.0.0
*/
public final class Island {
/**
* The session.
*/
public final Session session;
/**
* The schematic.
*/
public final dev.loki.loparkour.schematic.lpschem.LPSchematic schematic;
/**
* The blocks that have been affected by the schematic.
*/
public List<Block> blocks;
public Island(@NotNull Session session, @Nullable dev.loki.loparkour.schematic.lpschem.LPSchematic schematic) {
this.session = session;
this.schematic = schematic;
}
/**
* Builds the island and teleports the player.
*/
public void build(Location location) {
if (schematic == null) {
LoParkour.getPlugin().getLogger().warning("Cannot build island - schematic is null!");
return;
}
blocks = schematic.paste(location, location.getWorld());
Material playerMaterial = Material.getMaterial(Config.GENERATION.getString("advanced.island.spawn.player-block").toUpperCase());
Material parkourMaterial = Material.getMaterial(Config.GENERATION.getString("advanced.island.parkour.begin-block").toUpperCase());
// Fallback for first-block-material if not present in config
String firstBlockStr = "stone";
try {
firstBlockStr = Config.GENERATION.getString("advanced.island.parkour.first-block-material");
} catch (NoSuchElementException ex) {
LoParkour.getPlugin().getLogger().warning("Config key 'advanced.island.parkour.first-block-material' not found, using 'stone' as default");
}
Material firstBlockMaterial = Material.getMaterial(firstBlockStr.toUpperCase());
try {
Block player = blocks.stream().filter(block -> block.getType() == playerMaterial).findAny().orElseThrow();
Block parkour = blocks.stream().filter(block -> block.getType() == parkourMaterial).findAny().orElseThrow();
player.setType(firstBlockMaterial);
parkour.setType(firstBlockMaterial);
Location ps = player.getLocation().add(0.5, 1.0, 0.5);
ps.setYaw(Config.GENERATION.getInt("advanced.island.spawn.yaw"));
ps.setPitch(Config.GENERATION.getInt("advanced.island.spawn.pitch"));
// First parkour block position - fixed offset from parkour marker
// Always 4 blocks in the direction of heading from center
Location parkourStart = parkour.getLocation().clone();
parkourStart.add(
session.generator.state.heading.getX() * 4,
0,
session.generator.state.heading.getZ() * 4
);
session.generator.generateFirst(ps, parkourStart);
session.generator.startTick();
session.getPlayers().forEach(pp -> pp.setup(ps));
} catch (NoSuchElementException ex) {
LoParkour.getPlugin().getLogger().severe("Error while trying to find parkour or player spawn in schematic %s - check if you used the same material as the one in generation.yml - ".formatted("schematic") + ex.getMessage());
blocks.forEach(block -> block.setType(Material.AIR));
}
}
/**
* Destroys the island.
*/
public void destroy() {
if (blocks == null) {
return;
}
blocks.forEach(block -> block.setType(Material.AIR, false));
}
}