From 8642a5f4d822305c374a0e860f8091e38c3eb778 Mon Sep 17 00:00:00 2001 From: yoyosource Date: Sat, 19 Aug 2023 16:19:54 +0200 Subject: [PATCH] Add WorldConfig.TowerGeneratorDoorBlock Update TowerGenerator --- configs/mciv.yml | 6 +- configs/steamtower.yml | 40 +++++++++ .../steamwar/towerrun/config/WorldConfig.java | 63 ++++++++++++++ .../towerrun/generator/TowerGenerator.java | 87 ++++++++++++++++++- 4 files changed, 190 insertions(+), 6 deletions(-) diff --git a/configs/mciv.yml b/configs/mciv.yml index 79fc54e..20fce57 100644 --- a/configs/mciv.yml +++ b/configs/mciv.yml @@ -15,11 +15,11 @@ tower: doors: 1: x: 138 - y: 229 + y: 228 z: 858 2: x: 137 - y: 229 + y: 228 z: 858 lavaY: 255 laveSpace: 7 @@ -32,7 +32,7 @@ tower: minX: 93 maxX: 167 minZ: 813 -maxZ: 863 +maxZ: 883 winconditions: - LAST_REMAINING diff --git a/configs/steamtower.yml b/configs/steamtower.yml index 1f820a1..43b94d3 100644 --- a/configs/steamtower.yml +++ b/configs/steamtower.yml @@ -64,6 +64,8 @@ towerGenerator: x: 0 y: 12 z: 0 + minHeight: 200 + maxHeight: 250 schematicType: steamtower fillRegions: 1: @@ -87,6 +89,44 @@ towerGenerator: maxZ: 46 percentage: 1.0 material: MANGROVE_ROOTS + minNoBombFloors: 2 + maxNoBombFloors: 7 + minBombs: 20 + maxBombs: 60 + tntChance: 0.3 + tntRegions: + 1: + minX: 3 + minZ: 3 + maxX: 26 + maxZ: 76 + 2: + minX: 43 + minZ: 3 + maxX: 66 + maxZ: 76 + 3: + minX: 27 + minZ: 53 + maxX: 42 + maxZ: 76 + 4: + minX: 27 + minZ: 3 + maxX: 42 + maxZ: 26 + keyChance: 0.3 + minNoKeyFloors: 2 + maxNoKeyFloors: 7 + doorBlocks: + 1: + x: 30 + dy: 1 + z: 35 + 2: + x: 30 + dy: 1 + z: 36 minX: -28 maxX: 98 diff --git a/src/de/steamwar/towerrun/config/WorldConfig.java b/src/de/steamwar/towerrun/config/WorldConfig.java index 1f84875..fafdd45 100644 --- a/src/de/steamwar/towerrun/config/WorldConfig.java +++ b/src/de/steamwar/towerrun/config/WorldConfig.java @@ -214,13 +214,35 @@ public class WorldConfig { public final int x; public final int y; public final int z; + public final int minHeight; + public final int maxHeight; + public final int minNoBombFloors; + public final int maxNoBombFloors; + public final double tntChance; + public final int minBombs; + public final int maxBombs; + public final double keyChance; + public final int minNoKeyFloors; + public final int maxNoKeyFloors; public final SchematicType schematicType; public final TowerGeneratorFillRegion[] fillRegions; + public final Region[] tntRegions; + public final TowerGeneratorDoorBlock[] doorBlocks; public TowerGeneratorConfig(ConfigurationSection section) { x = section.getInt("x"); y = section.getInt("y"); z = section.getInt("z"); + minHeight = section.getInt("minHeight"); + maxHeight = section.getInt("maxHeight"); + minNoBombFloors = section.getInt("minNoBombFloors"); + maxNoBombFloors = section.getInt("maxNoBombFloors"); + minBombs = section.getInt("minBombs"); + maxBombs = section.getInt("maxBombs"); + tntChance = section.getDouble("tntChance"); + keyChance = section.getDouble("keyChance"); + minNoKeyFloors = section.getInt("minNoKeyFloors"); + maxNoKeyFloors = section.getInt("maxNoKeyFloors"); schematicType = SchematicType.fromDB(section.getString("schematicType")); ConfigurationSection fillRegionsSection = section.getConfigurationSection("fillRegions"); @@ -236,6 +258,34 @@ public class WorldConfig { } else { fillRegions = new TowerGeneratorFillRegion[0]; } + + ConfigurationSection tntRegionsSection = section.getConfigurationSection("tntRegions"); + if (tntRegionsSection != null) { + List tntRegions = tntRegionsSection.getKeys(false).stream() + .map(tntRegionsSection::getConfigurationSection) + .toList(); + + this.tntRegions = new Region[tntRegions.size()]; + for (int i = 0; i < tntRegions.size(); i++) { + this.tntRegions[i] = new Region(tntRegions.get(i)); + } + } else { + tntRegions = new Region[0]; + } + + ConfigurationSection doorBlocksSection = section.getConfigurationSection("doorBlocks"); + if (doorBlocksSection != null) { + List doorBlocks = doorBlocksSection.getKeys(false).stream() + .map(doorBlocksSection::getConfigurationSection) + .toList(); + + this.doorBlocks = new TowerGeneratorDoorBlock[doorBlocks.size()]; + for (int i = 0; i < doorBlocks.size(); i++) { + this.doorBlocks[i] = new TowerGeneratorDoorBlock(doorBlocks.get(i)); + } + } else { + doorBlocks = new TowerGeneratorDoorBlock[0]; + } } } @@ -257,4 +307,17 @@ public class WorldConfig { material = Material.valueOf(section.getString("material")); } } + + @Getter + public static final class TowerGeneratorDoorBlock { + private final int x; + private final int dy; + private final int z; + + public TowerGeneratorDoorBlock(ConfigurationSection section) { + x = section.getInt("x"); + dy = section.getInt("dy"); + z = section.getInt("z"); + } + } } diff --git a/src/de/steamwar/towerrun/generator/TowerGenerator.java b/src/de/steamwar/towerrun/generator/TowerGenerator.java index 03d6318..60d73a8 100644 --- a/src/de/steamwar/towerrun/generator/TowerGenerator.java +++ b/src/de/steamwar/towerrun/generator/TowerGenerator.java @@ -17,12 +17,18 @@ import de.steamwar.towerrun.game.TowerRunGame; import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.block.Block; +import org.bukkit.Material; +import org.bukkit.block.*; +import org.bukkit.block.data.Bisected; +import org.bukkit.block.data.type.Door; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; import org.bukkit.scheduler.BukkitRunnable; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Random; @@ -66,11 +72,14 @@ public class TowerGenerator { public void generate() { new BukkitRunnable() { - int height = random.nextInt(50) + 200; + int height = random.nextInt(config.maxHeight - config.minHeight) + config.minHeight; int y = TowerGenerator.this.config.y; + int noBombFloors; + int noKeyFloors; { - TowerGenerator.this.height = height; + noBombFloors = random.nextInt(config.maxNoBombFloors - config.minNoBombFloors) + config.minNoBombFloors; + noKeyFloors = random.nextInt(config.maxNoKeyFloors - config.minNoKeyFloors) + config.minNoKeyFloors; } @Override @@ -79,21 +88,93 @@ public class TowerGenerator { SchematicNode schematicNode = allSchematics.get(random.nextInt(allSchematics.size())); SchematicData schematicData = new SchematicData(schematicNode); int currentY; + int width; + int depth; try { Clipboard clipboard = schematicData.load(); try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) { ClipboardHolder ch = new ClipboardHolder(clipboard); Operations.completeBlindly(ch.createPaste(e).to(BlockVector3.at(config.x, y, config.z)).build()); } + width = clipboard.getDimensions().getX(); + depth = clipboard.getDimensions().getZ(); currentY = y; y += clipboard.getDimensions().getY(); height -= clipboard.getDimensions().getY(); + TowerGenerator.this.height += clipboard.getDimensions().getY(); } catch (IOException e) { allSchematics.remove(schematicNode); return; } spawn = WorldConfig.SPAWN.clone().add(0, y, 0); + List chestBlocks = new ArrayList<>(); + for (int x = config.x; x < config.x + width; x++) { + for (int z = config.z; z < config.z + depth; z++) { + for (int y = currentY; y < this.y; y++) { + Block block = Bukkit.getWorlds().get(0).getBlockAt(x, y, z); + BlockState blockState = block.getState(); + if (blockState instanceof Chest) { + chestBlocks.add((Container) blockState); + } + } + } + } + + noBombFloors--; + if (noBombFloors < 0 && random.nextDouble() < config.tntChance) { + noBombFloors = random.nextInt(config.maxNoBombFloors - config.minNoBombFloors) + config.minNoBombFloors; + int bombCount = random.nextInt(config.maxBombs - config.minBombs) + config.minBombs; + for (int i = 0; i < bombCount; i++) { + WorldConfig.Region region = config.tntRegions[random.nextInt(config.tntRegions.length)]; + int x = random.nextInt(region.max.getBlockX() - region.min.getBlockX()) + region.min.getBlockX(); + int z = random.nextInt(region.max.getBlockZ() - region.min.getBlockZ()) + region.min.getBlockZ(); + int y = currentY + 1; + Bukkit.getWorlds().get(0).getBlockAt(x, y, z).setType(Material.TNT, true); + } + } + + noKeyFloors--; + if (!chestBlocks.isEmpty() && noKeyFloors < 0 && random.nextDouble() < config.keyChance) { + noKeyFloors = random.nextInt(config.maxNoKeyFloors - config.minNoKeyFloors) + config.minNoKeyFloors; + Inventory inventory = chestBlocks.get(random.nextInt(chestBlocks.size())).getInventory(); + inventory.addItem(new ItemStack(Material.LEVER, 1)); + + for (WorldConfig.TowerGeneratorDoorBlock doorBlock : config.doorBlocks) { + int x = doorBlock.getX(); + int y = currentY + doorBlock.getDy(); + int z = doorBlock.getZ(); + Block block = Bukkit.getWorlds().get(0).getBlockAt(x, y, z); + for (int i = 0; i < 5; i++) { + if (block.getType().isAir()) { + block.setType(Material.IRON_BLOCK, true); + block = block.getRelative(0, 1, 0); + } else { + break; + } + } + + Bukkit.getScheduler().runTaskLater(TowerRun.getInstance(), () -> { + Block door = Bukkit.getWorlds().get(0).getBlockAt(x, y, z); + door.setType(Material.IRON_DOOR, true); + door = door.getRelative(0, 1, 0); + door.setType(Material.IRON_DOOR, true); + }, 10); + Bukkit.getScheduler().runTaskLater(TowerRun.getInstance(), () -> { + Block door = Bukkit.getWorlds().get(0).getBlockAt(x, y, z); + Door doorState = (Door) door.getBlockData(); + doorState.setFacing(BlockFace.EAST); + door.setBlockData(doorState, true); + + door = door.getRelative(0, 1, 0); + doorState = (Door) door.getBlockData(); + doorState.setFacing(BlockFace.EAST); + doorState.setHalf(Bisected.Half.TOP); + door.setBlockData(doorState, true); + }, 20); + } + } + for (WorldConfig.TowerGeneratorFillRegion fillRegion : config.fillRegions) { for (int x = fillRegion.getMinX(); x < fillRegion.getMaxX(); x++) { for (int z = fillRegion.getMinZ(); z < fillRegion.getMaxZ(); z++) {